全国咨询/投诉热线:400-618-4000

Java培训实战教程之论Socket的重要性

更新时间:2016年01月19日14时37分 来源:传智播客Java培训学院 浏览次数:

Java培训中 精点、难点知识总结汇总
Socket不仅在聊天应用程序中需要用到,而且对于学习Asp.net也非常有帮助。你懂得!
实现服务端和客户端互发信息,以及服务端向多个客户端发送信息。
     服务端代码1:
  1.         public Form1()
  2.         {
  3.             InitializeComponent();
  4.             Control.CheckForIllegalCrossThreadCalls = false;
  5.         }
  6.         //创建监听用的socket
  7.         private void btnStartMonitor_Click(object sender, EventArgs e)
  8.         {
  9.             //监听的ip地址
  10.             IPAddress ip = IPAddress.Parse(txtIP.Text);
  11.             //监听的ip地址和端口号
  12.             IPEndPoint point = new IPEndPoint(ip, int.Parse(txtPortNumber.Text));
  13.             //监听用的socket
  14.             Socket socket = new Socket(AddressFamily.InterNetwork, SocketType.Stream, ProtocolType.Tcp);
  15.             //通常每个套接字地址(协议/网络地址/端口)只允许使用一次
  16.             //绑定监听的ip地址和端口号
  17.             socket.Bind(point);
  18.             //监听端口   监听队列的长度:同一个时间等待的个数。
  19.             socket.Listen(10);
  20.             //点击之后,禁用掉按钮
  21.             btnStartMonitor.Enabled = false;
  22.             //提示用户程序开始运行了
  23.             ShowMsg("开始运行了...");
  24.             //监听端口,如果有客户端连接,创建通信用socket
  25.             //阻塞窗体的运行
  26.             //Socket connSocket = socket.Accept();
  27.             //用线程来解决窗体假死的问题
  28.             Thread th = new Thread(Listen);
  29.             th.IsBackground = true;//后台线程
  30.             th.Start(socket);
  31.         }
  32.         //监听是否有客户端连接
  33.         void Listen(object o)
  34.         {
  35.             //监听用的socket
  36.             Socket socket = o as Socket;
  37.             //监听端口
  38.             Socket connSocket = socket.Accept();
  39.             //显示远程连接的IP地址和端口号
  40.             ShowMsg(connSocket.RemoteEndPoint.ToString());
  41.         }
  42.         //在文本框显示信息
  43.         void ShowMsg(string msg)
  44.         {
  45.             txtShowMessage.AppendText(msg + "\r\n");
  46.         }
复制代码
以上代码只能让一个客户端连接服务端,弊端。
     服务端代码2完善——循环接收客户端连接:
  1.         //监听是否有客户端连接
  2.        void Listen(object o)
  3.         {
  4.             //监听用的socket
  5.             Socket socket = o as Socket;
  6.             //可以不停地接受客户端的连接
  7.             while (true)
  8.             {
  9.                 //负责通信用的socket
  10.                 Socket connSocket = socket.Accept();
  11.                 //显示远程连接的IP地址和端口号
  12.                 ShowMsg(connSocket.RemoteEndPoint.ToString());
  13.                 //本机的IP地址和端口号
  14.                 //connSocket.LocalEndPoint
  15.                 //接收数据
  16.                 byte[] buffer = new byte[1024 * 1023];
  17.                 //接收数据,把数据发到buffer中
  18.                 //num是实际接收到的字节个数
  19.                 int num=connSocket.Receive(buffer);
  20.                 //把实际有效的字节转换成字符串
  21.                 string str = Encoding.UTF8.GetString(buffer, 0, num);
  22.                 ShowMsg(str);
  23.             }
  24.         }
复制代码
服务端代码3完善——循环接收消息:
  1.         //监听是否有客户端连接
  2.         void Listen(object o)
  3.         {
  4.             //监听用的socket
  5.             Socket socket = o as Socket;
  6.             //可以不停地接受客户端的连接
  7.             while (true)
  8.             {
  9.                 //负责通信用的socket
  10.                 Socket connSocket = socket.Accept();
  11.                 //显示远程连接的IP地址和端口号
  12.                 ShowMsg(connSocket.RemoteEndPoint.ToString());
  13.                 //本机的IP地址和端口号
  14.                 //connSocket.LocalEndPoint
  15. //循环接收消息
  16. while(true)
  17. {
  18.                 //接收数据
  19.                 byte[] buffer = new byte[1024 * 1023];
  20.                 //接收数据,把数据发到buffer中
  21.                 //num是实际接收到的字节个数
  22.                 int num=connSocket.Receive(buffer);
  23.                 //把实际有效的字节转换成字符串
  24.                 string str = Encoding.UTF8.GetString(buffer, 0, num);
  25.                 ShowMsg(str);
  26. }
  27.             }
  28.         }
复制代码
服务端代码4完善——循环多个客户端并接收信息:
  1.         //监听是否有客户端连接
  2.         void Listen(object o)
  3.         {
  4.             //监听用的socket
  5.             Socket socket = o as Socket;
  6.             //可以不停地接受客户端的连接
  7.             while (true)
  8.             {
  9.                 //负责通信用的socket
  10.                 Socket connSocket = socket.Accept();
  11.                 //显示远程连接的IP地址和端口号
  12.                 ShowMsg(connSocket.RemoteEndPoint.ToString());
  13.                 //本机的IP地址和端口号
  14.                 //connSocket.LocalEndPoint
  15.                 //线程接收信息
  16.                 Thread th = new Thread(RecMsg);
  17.                 th.IsBackground = true;
  18.                 th.Start(connSocket);            
  19. }
  20.         }
  21.         //接收信息
  22.         void RecMsg(object o)
  23.         {
  24.             //通信用的socket
  25.             Socket connSocket = o as Socket;
  26.             //可以不停地接受客户端的内容
  27.             while (true)
  28.             {
  29.                 //接受数据
  30.                 byte[] buffer = new byte[1024 * 1024];
  31.                 //接受数据,把数据发到buffer中
  32.                 //num就是实际接受到的字节个数
  33.                 int num = connSocket.Receive(buffer);
  34. //当telnet关闭,会不停的发送空(0)字节
  35.                 //把实际有效的字节转化成字符串
  36.                 string str = Encoding.UTF8.GetString(buffer, 0, num);
  37.                 ShowMsg(connSocket.RemoteEndPoint.ToString() + ":" + str);
  38.                 }
  39.             }
  40.         }
复制代码
服务端代码5完善——限制客户端连接数:
  1.         //限制连接客户端的个数
  2.         int count=0;
  3.         void Listen(object o)
  4.         {
  5.             //监听用的socket
  6.             Socket socket = o as Socket;
  7.             //可以不停地接受客户端的连接
  8.             while (count<1000)
  9.             {
  10.                 //负责通信用的socket
  11.                 Socket connSocket = socket.Accept();
  12.                 //显示远程连接的IP地址和端口号
  13.                 ShowMsg(connSocket.RemoteEndPoint.ToString());
  14.                 //本机的IP地址和端口号
  15.                 //connSocket.LocalEndPoint
  16.                 //线程接收信息
  17.                 Thread th = new Thread(RecMsg);
  18.                 th.IsBackground = true;
  19.                 th.Start(connSocket);
  20. }
  21.         }
复制代码
服务端代码6完善——解决“当tenet关闭,会不停地发送空(0)字节”:
  1.         //接收信息
  2.         void RecMsg(object o)
  3.         {
  4.             //通信用的socket
  5.             Socket connSocket = o as Socket;
  6.             //可以不停地接受客户端的内容
  7.             while (true)
  8.             {
  9.                 //接受数据
  10.                 byte[] buffer = new byte[1024 * 1024];
  11.                 //接受数据,把数据发到buffer中
  12.                 //num就是实际接受到的字节个数
  13.                 int num = connSocket.Receive(buffer);
  14. //当telnet关闭,会不停的发送空(0)字节
  15.                     //当telnet关闭,会不停的发送(0)个字节  客户端断开
  16.                     if (num == 0)
  17.                     {
  18.                         ShowMsg(connSocket.RemoteEndPoint.ToString() + ":退出");
  19.                         connSocket.Shutdown(SocketShutdown.Receive);
  20.                         connSocket.Close();
  21.                         break;
  22.                     }
  23.                 //把实际有效的字节转化成字符串
  24.                 string str = Encoding.UTF8.GetString(buffer, 0, num);
  25.                 ShowMsg(connSocket.RemoteEndPoint.ToString() + ":" + str);
  26.                 }
  27.             }
  28.         }
复制代码
客户端代码1:
  1.         public Form1()
  2.         {
  3.             InitializeComponent();
  4.             Control.CheckForIllegalCrossThreadCalls = false;
  5.         }
  6.         //连接服务端和发送信息都要用到同一个socket,将其定义到外边
  7.         Socket socket;
  8.         //连接服务端
  9.         private void btnConnect_Click(object sender, EventArgs e)
  10.         {
  11.             //客户端连接服务器的ip地址
  12.             IPAddress ip = IPAddress.Parse(txtIP.Text);
  13.             //客户端连接的服务器的ip地址和端口号
  14.             IPEndPoint point = new IPEndPoint(ip, int.Parse(txtPortNumber.Text));
  15.             //创建连接使用的socket
  16. socket = new Socket(AddressFamily.InterNetwork, SocketType.Stream, ProtocolType.Tcp);
  17.             try
  18.             {
  19.                 //连接聊天服务器
  20.                 //服务器没开报错
  21.                 //由于目标计算机积极拒绝,无法连接。
  22.                 socket.Connect(point);
  23.                 ShowMsg("连接成功");
  24.             }
  25.             catch (Exception ex)
  26.             {
  27.                 ShowMsg(ex.Message);
  28.             }
  29.         }
  30.         void ShowMsg(string msg)
  31.         {
  32.             txtShowMessage.AppendText(msg + "\r\n");
  33.         }
  34.         //发送消息
  35.         private void btnSendMessage_Click(object sender, EventArgs e)
  36.         {
  37.             if (socket != null)
  38.             {
  39.                 byte[] buffer = Encoding.UTF8.GetBytes(txtInputMessage.Text);
  40.                 socket.Send(buffer);
  41.             }
  42.             else
  43.             {
  44.                 MessageBox.Show("请先连接");
  45.             }
  46.         }
复制代码
客户端代码7完善——服务端知道客户端关闭的消息:
  1.         //接收信息
  2.         void RecMsg(object o)
  3.         {
  4.             //通信用的socket
  5.             Socket connSocket = o as Socket;
  6.             //可以不停地接受客户端的内容
  7.             while (true)
  8.             {
  9.                 //接受数据
  10.                 byte[] buffer = new byte[1024 * 1024];
  11.                 //接受数据,把数据发到buffer中
  12.                 //num就是实际接受到的字节个数
  13.                 int num = -1;
  14.                 try
  15.                 {
  16.         //远程主机强迫关闭了一个现有的连接。  当客户端关闭,服务端未关闭时,报错。
  17.                     num = connSocket.Receive(buffer);
  18.                     //当telnet关闭,会不停的发送(0)个字节  客户端断开
  19.                     if (num == 0)
  20.                     {
  21.                         ShowMsg(connSocket.RemoteEndPoint.ToString() + ":退出");
  22.                         connSocket.Shutdown(SocketShutdown.Receive);
  23.                         connSocket.Close();
  24.                         break;
  25.                     }
  26.                     //把实际有效的字节转化成字符串
  27.                     string str = Encoding.UTF8.GetString(buffer, 0, num);
  28.                     ShowMsg(connSocket.RemoteEndPoint.ToString() + ":" + str);
  29.                 }
  30.                 catch (Exception ex)
  31.                 {
  32.                     ShowMsg(ex.Message);
  33.                     //出现异常,跳出循环
  34.                     break;
  35.                 }
  36.             }
  37.         }
复制代码
服务端代码8完善——服务端给客户端发送消息:
  1.         //发送消息
  2.         private void btnSendMessage_Click(object sender, EventArgs e)
  3.         {
  4.             if (connSocket!=null)
  5.             {
  6.                 byte[] buffer = Encoding.UTF8.GetBytes(txtInputMessage.Text);
  7.                 try
  8.                 {
  9.                     connSocket.Send(buffer);
  10.                 }
  11.                 catch (Exception ex)
  12.                 {
  13.                     ShowMsg(ex.Message);
  14.                 }
  15.             }
  16.         }
复制代码
客户端代码2完善——客户端接收服务端发送的消息:
  1.         //接收消息
  2.         void RecMsg()
  3.         {
  4.             while (true)
  5.             {
  6.                 byte[] buffer = new byte[1024 * 1024];
  7.                 try
  8.                 {
  9.                     int num = socket.Receive(buffer);
  10.                     string str = Encoding.UTF8.GetString(buffer, 1, num );
  11.                     ShowMsg(str);
  12.                 }
  13.                 catch (Exception ex)
  14.                 {
  15.                     ShowMsg(ex.Message);
  16.                     break;
  17.                 }
  18.             }
  19.         }
  20. //由于接收消息是一个死循环,需要用到线程
  21.                 //线程接受消息
  22.                 Thread th = new Thread(RecMsg);
  23.                 th.IsBackground = true;
  24.                 th.Start();
复制代码
服务端代码9完善——服务端给指定客户端发送消息:
  1.         //存储通信用的socket字典
  2.         Dictionary<string, Socket> dic = new Dictionary<string, Socket>();
  3.         //限制连接客户端的个数
  4.         int count = 0;
  5.         //监听是否有客户端连接
  6.         void Listen(object o)
  7.         {
  8.             //监听用的socket
  9.             Socket socket = o as Socket;
  10.             //可以不停地接受客户端的连接
  11.             while (count < 100)
  12.             {
  13.                 count++;
  14.                 //监听端口,如果有客户端连接,创建通信用socket
  15.                 Socket connSocket = socket.Accept();
  16.                 //显示远程连接的IP地址和端口号
  17.                 ShowMsg(connSocket.RemoteEndPoint.ToString());
  18.                 //本机的IP地址和端口号
  19.                 //connSocket.LocalEndPoint
  20.                 //保存当前登录的客户端的socket
  21.                 string ipport = connSocket.RemoteEndPoint.ToString();
  22.                 cboUser.Items.Add(ipport);
  23.                 dic.Add(ipport, connSocket);
  24.                 //线程接收信息
  25.                 Thread th = new Thread(RecMsg);
  26.                 th.IsBackground = true;
  27.                 th.Start(connSocket);
  28.             }
  29.         }
  30.         //发送消息
  31.         private void btnSendMessage_Click(object sender, EventArgs e)
  32.         {
  33.             //获取下拉框中选择的ip和端口号
  34.             string ipport = cboUser.Text;
  35.             if (!string.IsNullOrEmpty(ipport))
  36.             {
  37.                 byte[] buffer = Encoding.UTF8.GetBytes(txtInputMessage.Text);
  38.                 try
  39.                 {
  40.                     //根据key获得socket
  41.                     Socket connSocket = dic[ipport];
  42.                     connSocket.Send(buffer);
  43.                 }
  44.                 catch (Exception ex)
  45.                 {
  46.                     ShowMsg(ex.Message);
  47.                 }
  48.             }
  49.             else
  50.             {
  51.                 MessageBox.Show("请选择客户端");
  52.             }
  53.         }
复制代码
Java培训学院始终认为你将会是最优秀的存在,你就是最棒的,看好你,加油!!!
本文版权归传智播客Java培训学院所有,欢迎转载,转载请注明作者出处。谢谢!
作者:传智播客Java培训学院
首发:http://www.itcast.cn/javaee