前段时间被问到Socket,当时懵圈了。只记得在学习网络编程的时候了解过这个,具体的实现步骤只剩下一点模糊的印象了。所以,借助百度又重新学习了一下Socket。
文章代码照着陈希章老师的代码写了一遍,只是将控制台程序改成了winform程序,复习了Socket通信流程。
陈老师博客链接(向初学Socket的同学强力推荐):http://www.cnblogs.com/chenxizhang/archive/2011/09/10/2172994.html#!comments
服务端代码:
1 public partial class FormServer : Form 2 { 3 4 static byte[] buffer = new byte[1024]; 5 6 public FormServer() 7 { 8 InitializeComponent(); 9 }10 11 private void FormServer_Load(object sender, EventArgs e)12 {13 Socket socket = new Socket(AddressFamily.InterNetwork, SocketType.Stream, ProtocolType.Tcp);//生成socket14 socket.Bind(new IPEndPoint(IPAddress.Any, 4530));//绑定socket15 socket.Listen(4);//监听socket,并设置队列长度16 socket.BeginAccept(new AsyncCallback(ClientAccepted), socket);17 txtShowMessage.Invoke(new MethodInvoker(delegate { txtShowMessage.AppendText("服务端初始化完成\r\n"); }));18 }19 20 21 public static void ReceiveMessage(IAsyncResult ar)22 {23 try24 {25 var socket = ar.AsyncState as Socket;26 27 var length = socket.EndReceive(ar);28 //读取出来消息内容29 var message = Encoding.Unicode.GetString(buffer, 0, length);30 //显示消息31 txtShowMessage.Invoke(new MethodInvoker(delegate { txtShowMessage.AppendText(message+"\r\n"); }));32 33 //接收下一个消息(因为这是一个递归的调用,所以这样就可以一直接收消息了)34 socket.BeginReceive(buffer, 0, buffer.Length, SocketFlags.None, new AsyncCallback(ReceiveMessage), socket);35 }36 catch (Exception ex)37 {38 txtShowMessage.AppendText(ex.Message + "\r\n");39 }40 }41 42 43 public static void ClientAccepted(IAsyncResult ar)44 {45 46 var socket = ar.AsyncState as Socket;47 48 //这就是客户端的Socket实例,我们后续可以将其保存起来49 var client = socket.EndAccept(ar);50 51 //给客户端发送一个欢迎消息52 client.Send(Encoding.Unicode.GetBytes("Hi there, I accept you request at " + DateTime.Now.ToString()));53 54 55 //实现每隔两秒钟给服务器发一个消息56 //这里我们使用了一个定时器57 var timer = new System.Timers.Timer();58 timer.Interval = 2000D;59 timer.Enabled = true;60 timer.Elapsed += (o, a) =>61 {62 //检测客户端Socket的状态63 if (client.Connected)64 {65 try66 {67 client.Send(Encoding.Unicode.GetBytes("Message from server at " + DateTime.Now.ToString()));68 }69 catch (SocketException ex)70 {71 txtShowMessage.AppendText(ex.Message + "\r\n");72 }73 }74 else75 {76 timer.Stop();77 timer.Enabled = false;78 txtShowMessage.AppendText("Client is disconnected, the timer is stop.\r\n");79 }80 };81 timer.Start();82 83 84 //接收客户端的消息(这个和在客户端实现的方式是一样的)85 client.BeginReceive(buffer, 0, buffer.Length, SocketFlags.None, new AsyncCallback(ReceiveMessage), client);86 87 //准备接受下一个客户端请求88 socket.BeginAccept(new AsyncCallback(ClientAccepted), socket);89 }90 }
客户端代码:
1 public partial class FormClient : Form 2 { 3 public FormClient() 4 { 5 InitializeComponent(); 6 } 7 // Socket socket;//接收服务端数据socket对象 8 static byte[] buffer = new byte[1024]; 9 string message = string.Empty;//服务端传过来的数据10 private void FormClient_Load(object sender, EventArgs e)11 {12 Socket socket = new Socket(AddressFamily.InterNetwork, SocketType.Stream, ProtocolType.Tcp);//创建socket13 socket.Connect("127.0.0.1", 4530);//根据IP地址和端口进行连接14 15 socket.BeginReceive(buffer, 0, buffer.Length, SocketFlags.None, new AsyncCallback(ReceiveMessage), socket);16 //接受用户输入,将消息发送给服务器端17 while (true)18 {19 var message = "Message from client : " + Console.ReadLine();20 var outputBuffer = Encoding.Unicode.GetBytes(message);21 socket.BeginSend(outputBuffer, 0, outputBuffer.Length, SocketFlags.None, null, null);22 }23 }24 25 26 27 public void ReceiveMessage(IAsyncResult ar)28 {29 try30 {31 var socket = ar.AsyncState as Socket;32 var length = socket.EndReceive(ar);33 //读取出来消息内容34 var message = Encoding.Unicode.GetString(buffer, 0, length);35 //显示消息36 txtShowMessage.Invoke(new MethodInvoker(delegate { txtShowMessage.AppendText(message+"\r\n"); }));37 //接收下一个消息(因为这是一个递归的调用,所以这样就可以一直接收消息了)38 socket.BeginReceive(buffer, 0, buffer.Length, SocketFlags.None, new AsyncCallback(ReceiveMessage), socket);39 40 }41 catch (Exception ex)42 {43 txtShowMessage.AppendText(ex.Message + "\r\n");44 }45 }46 }
运行结果: