龙空技术网

C#实现Socket多人聊天-无服务器 直联版

编程老大叔 1277

前言:

如今小伙伴们对“c语言socketwindows”大概比较重视,朋友们都想要了解一些“c语言socketwindows”的相关知识。那么小编也在网上搜集了一些对于“c语言socketwindows””的相关知识,希望看官们能喜欢,咱们一起来学习一下吧!

前面有一篇文章写了关于Socket的一些理解,今天小编就用C#来实现以下某聊天软件的多人聊天系统(别问我为啥不用C++,只是因为C#效率高,一个字爽啊)。

我们先来看一下整体的思路:

整体思路是利用线程池达到接收多个聊天请求。先初始化Socket,然后与端口绑定(bind),对端口进行监听(listen),调用accept阻塞,等待客户端连接。在这时如果有个客户端初始化一个Socket,然后连接服务器(connect),如果连接成功,这时请求端与接收端的连接就建立了。客户端发送数据请求,服务器端接收请求并处理请求,然后把回应数据发送给客户端,客户端读取数据

前端页面很简单,一个显示框一个输入框:

具体代码实现:

using System;using System.Collections.Generic;using System.ComponentModel;using System.Data;using System.Drawing;using System.Linq;using System.Text;using System.Windows.Forms;using System.Net.Sockets;using System.Net;using System.Threading;namespace WindowsFormsApplication2{ public partial class Form1 : Form { public delegate void CallBack(string str); public Socket socListen = new Socket(AddressFamily.InterNetwork, SocketType.Stream, ProtocolType.Tcp); public Form1() { InitializeComponent(); CheckForIllegalCrossThreadCalls = false; } private void Form1_Load(object sender, EventArgs e) { string ip_server = string.Empty; //获取主机名 string name = Dns.GetHostName(); //通过主机名获取本地IP(包含所有IP,有几个网卡就有几个IP,IP分IPV4和IPV6,这里要注意我们用IPV4) IPAddress[] ipadrlist = Dns.GetHostAddresses(name);  foreach (IPAddress ipa in ipadrlist) { //筛选出我们要的IP,这里因为我是多个网卡,所以我需要这样筛选,大家可以用自己的特征去筛选 IP我打码了 if (ipa.ToString().Contains("!!!!!!")) ip_server = ipa.ToString(); } //小编自己用,大家可以不理会 ip_server = ipadrlist[3].ToString();  //注意,你要用的端口,这个端口要确保没有被占用 int port = 6000; IPAddress address = IPAddress.Parse(ip_server); //创建网络端口,包括ip和端口 IPEndPoint endPoint = new IPEndPoint(address, port); // 绑定套接字 socListen.Bind(endPoint); socListen.Listen(5); //创建线程,开始接受请求,因为Accept方法会阻塞,所以要用多线程 Thread thread = new Thread(acceptConnect); thread.Start(); } private void button1_Click(object sender, EventArgs e) { //为简单起见,限制聊天消息在1024个字节 string msg = richTextBox2.Text.Trim(); if (msg.Length > 1024) { MessageBox.Show("the message is too long"); return; } byte[] btMsg = Encoding.UTF8.GetBytes(msg); byte[] buffer = new byte[1024]; if (!socListen.Connected) { try { //对方IP IPAddress address_Server = IPAddress.Parse("!!!!!!"); //除了对方IP 你还得知道对方的程序跑在什么端口 IPEndPoint endPoint_Server = new IPEndPoint(address_Server, 6000); //连接对方 socListen.Connect(endPoint_Server); } catch (Exception ex) { MessageBox.Show(ex.Message); } } //发送消息 int len = socListen.Send(btMsg, btMsg.Length, SocketFlags.None); richTextBox2.Clear(); } public void acceptConnect() { while (true) { Socket client = null; client = socListen.Accept(); //利用线程池循环接收多个请求 ThreadPool.QueueUserWorkItem(new WaitCallback(receiveMsg),client); } } //接收聊天消息 public void receiveMsg(object clientObj) { Socket client = clientObj as Socket; while (true) { byte[] bt = new byte[1024]; try { client.Receive(bt, bt.Length, SocketFlags.None); string msg = Encoding.UTF8.GetString(bt);  string clientEndPoint = client.RemoteEndPoint.ToString(); listBox1.Items.Add("from Clinet point:"+ 				 clientEndPoint.Substring(clientEndPoint.IndexOf(":")+1,clientEndPoint.Length-clientEndPoint.IndexOf(":")-1)); listBox1.Items.Add("\t" + msg); } catch (Exception ex) { client.Close(); } } } }}

地址运行效果如下:

注:

1、这里面还有很多细节小编没有去处理,核心功能是实现了的。但这并不是一个OK的工程,如果有这方面的需要的朋友,需要自己去处理细节问题。

2、 需要在Form1的构造函数内加上CheckForIllegalCrossThreadCalls = false;这行代码,不然子线程无法操作主界面的控件。

标签: #c语言socketwindows