上个项目中用到了Socket通讯,项目中直接借助SuperSocket实现,但是我觉得这毕竟是一个我没接触过的东西,所以也顺便学习了一下原生socket的使用,做了一个socket服务器与客户端的开发.本人菜鸟一枚,只做了一个简单的实现,希望有看到我博客的大佬不吝指点,抱拳!
socket通讯的相关知识的话,在博客园中的大佬们总结的贴子已经非常多,也很详细,忘记了就在去看。
这里总结一下原生的Socket和SuperSocket的使用(官方定义:SuperSocket 是一个轻量级, 跨平台而且可扩展的 .Net/Mono Socket 服务器程序框架。你无须了解如何使用 Socket, 如何维护 Socket 连接和 Socket 如何工作,但是你却可以使用 SuperSocket 很容易的开发出一款 Socket 服务器端软件,例如游戏服务器,GPS 服务器, 工业控制服务和数据采集服务器等等。)
下边是一个Socket测试工具 十分好用!
链接:https://pan.baidu.com/s/1ykEofUIZKE2yhe3mMyRbJw
提取码:m2nk
先从服务器端说起。服务器端先初始化Socket,然后与端口绑定(bind),对端口进行监听(listen),调用accept阻塞,等待客户端连接。在这时如果有个客户端初始化一个Socket,然后连接服务器(connect),如果连接成功,这时客户端与服务器端的连接就建立了。客户端发送数据请求,服务器端接收请求并处理请求,然后把回应数据发送给客户端,客户端读取数据,最后关闭连接,一次交互结束。
原生Socket实现SocketServer:
1 using System; 2 using System.Collections.Generic; 3 using System.ComponentModel; 4 using System.Data; 5 using System.Drawing; 6 using System.Linq; 7 using System.Text; 8 using System.Threading.Tasks; 9 using System.Windows.Forms; 10 using System.Net.Sockets; 11 using System.Net; 12 using System.Threading; 13 14 namespace DotnetSockets 15 { 16 public partial class DotnetSocketServer : Form 17 { 18 public DotnetSocketServer() 19 { 20 InitializeComponent(); 21 } 22 23 //存储已连接的客户端的泛型集合 24 private static Dictionary<string, Socket> socketList = new Dictionary<string, Socket>(); 25 26 /// <summary> 27 /// 接收连接 28 /// </summary> 29 /// <param name="obj"></param> 30 public void StartServer(object obj) 31 { 32 string str; 33 while (true) 34 { 35 //等待接收客户端连接 Accept方法返回一个用于和该客户端通信的Socket 36 Socket recviceSocket = ((Socket)obj).Accept(); 37 //获取客户端ip和端口号 38 str = recviceSocket.RemoteEndPoint.ToString(); 39 socketList.Add(str, recviceSocket); 40 //控件调用invoke方法 解决"从不是创建控件的线程访问它"的异常 41 cmb_socketlist.Invoke(new Action(() => { cmb_socketlist.Items.Add(str); })); 42 richTextBox1.Invoke(new Action(() => { richTextBox1.AppendText(str + "已连接" + "\r\n"); })); 43 44 //Accept()执行过后 当前线程会阻塞 只有在有客户端连接时才会继续执行 45 //创建新线程,监控接收新客户端的请求数据 46 Thread thread = new Thread(startRecive); 47 thread.IsBackground = true; 48 thread.Start(recviceSocket); 49 } 50 } 51 52 /// <summary> 53 /// 接收消息 54 /// </summary> 55 /// <param name="obj">客户端socket</param> 56 public void startRecive(object obj) 57 { 58 string str; 59 string ip; 60 while (true) 61 { 62 63 byte[] buffer = new byte[2048]; 64 int count; 65 try 66 { 67 //Receive(Byte[]) 从绑定的 Socket 套接字接收数据,将数据存入接收缓冲区。 68 //该方法执行过后同Accept()方法一样 当前线程会阻塞 等到客户端下一次发来数据时继续执行 69 count = ((Socket)obj).Receive(buffer); 70 ip = ((Socket)obj).RemoteEndPoint.ToString(); 71 if (count == 0) 72 { 73 cmb_socketlist.Invoke(new Action(() => { cmb_socketlist.Items.Remove(ip); })); 74 richTextBox1.Invoke(new Action(() => { richTextBox1.AppendText(ip + "已断开连接" + "\r\n"); })); 75 break; 76 } 77 else 78 { 79 str = Encoding.Default.GetString(buffer, 0, count); 80 richTextBox1.Invoke(new Action(() => { richTextBox1.AppendText("收到"+ip+"数据 " + str + "\r\n"); })); 81 82 } 83 } 84 catch (Exception) 85 { 86 87 88 } 89 } 90 }