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