zoukankan      html  css  js  c++  java
  • Socket通信

    前段时间被问到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);//生成socket
    14             socket.Bind(new IPEndPoint(IPAddress.Any, 4530));//绑定socket
    15             socket.Listen(4);//监听socket,并设置队列长度
    16             socket.BeginAccept(new AsyncCallback(ClientAccepted), socket);
    17             txtShowMessage.Invoke(new MethodInvoker(delegate { txtShowMessage.AppendText("服务端初始化完成
    "); }));
    18         }
    19 
    20 
    21         public static void ReceiveMessage(IAsyncResult ar)
    22         {
    23             try
    24             {
    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+"
    "); }));
    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 + "
    ");
    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                     try
    66                     {
    67                         client.Send(Encoding.Unicode.GetBytes("Message from server at " + DateTime.Now.ToString()));
    68                     }
    69                     catch (SocketException ex)
    70                     {
    71                         txtShowMessage.AppendText(ex.Message + "
    ");
    72                     }
    73                 }
    74                 else
    75                 {
    76                     timer.Stop();
    77                     timer.Enabled = false;
    78                     txtShowMessage.AppendText("Client is disconnected, the timer is stop.
    ");
    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);//创建socket
    13             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             try
    30             {
    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+"
    "); }));
    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 + "
    ");
    44             }
    45         }
    46     }

    运行结果:

  • 相关阅读:
    ubuntu apt 命令相关
    linux 常用命令
    sqli-labs 通关详解(sql注入知识点整理)
    运维手册2---查看机子的系统信息
    运维手册1---ssh命令:使用密钥文件进行登陆
    Java中的==和equals,常量池
    Java Persistence
    VSCode常用插件汇总
    VSCode常用插件之Auto Rename Tag使用
    ESLint 使用指南
  • 原文地址:https://www.cnblogs.com/sunice/p/6537627.html
Copyright © 2011-2022 走看看