TCP 套接字编程
服务器端实现步骤:
1、使用Socket类创建套接字。
2、利用Bind方法将创建的套接字绑定到指定的地址结构。
3、利用Listen方法设置套接字为监听模式,使得服务器进入被动打开状态。
4、接受客户端的连接请求。
5、接收、应答客户端的数据请求。
6、终止连接。
客户端实现步骤:
1、使用Socket类创建套接字。
2、调用Connect方法建立一个与TCP服务器的连接。
3、发送数据请求,接受服务器的数据应答。
4、终止连接。
一对一:客户端代码:
using System; using System.Net; using System.Net.Sockets; using System.Threading; using System.Text; namespace Client { class Problem { private static byte[] result = new byte[1024 * 1024]; static Socket ClientSocket = new Socket(AddressFamily.InterNetwork,SocketType.Stream,ProtocolType.Tcp); static void Main(string[] args) { int Port = 8222; IPAddress IP = IPAddress.Parse("127.0.0.1"); try { Console.WriteLine("连接服务器成功!!!"); ClientSocket.Connect(new IPEndPoint(IP,Port)); } catch(Exception ex) { Console.WriteLine("连接服务器失败,按回车键退出!"); return; } for(int i=0;i<10;i++) { try { Thread.Sleep(2000); int ReceiveLength = ClientSocket.Receive(result); Console.WriteLine("接收服务器消息:{0}",Encoding.ASCII.GetString(result,0,ReceiveLength)); Console.WriteLine("向服务器发送消息:"); string sb = Console.ReadLine(); string SendMessage = "向服务器发送消息:" + DateTime.Now + "\n" + sb; ClientSocket.Send(Encoding.ASCII.GetBytes(SendMessage)); } catch(Exception ex) { ClientSocket.Shutdown(SocketShutdown.Both); ClientSocket.Close(); } } Console.WriteLine("消息发送完毕!!!"); Console.WriteLine(); } } }服务器代码:
using System; using System.Net; using System.Net.Sockets; using System.Threading; using System.Text; namespace Server { class Program { public static void ListenClientConnect() { while(true) { Socket ClientSocket = ServerSocket.Accept();//send Console.WriteLine("向客户端发送消息:"); string sb = Console.ReadLine(); ClientSocket.Send(Encoding.ASCII.GetBytes("Server Say Hello:"+sb)); Thread thread = new Thread(ReceiveMessage); thread.Start(ClientSocket); } } public static void ReceiveMessage(Object ClientSocket) { Socket MyClientSocket = (Socket)ClientSocket; while(true) { try { int ReceiveNum = MyClientSocket.Receive(result); Console.WriteLine("接受客户端{0}消息{1}:" ,MyClientSocket.RemoteEndPoint.ToString(), Encoding.ASCII.GetString(result,0,ReceiveNum)); Console.WriteLine("向客户端发送消息:"); string sb = Console.ReadLine(); MyClientSocket.Send(Encoding.ASCII.GetBytes(sb)); } catch(Exception ex) { Console.WriteLine("404 Not found!!!"); MyClientSocket.Shutdown(SocketShutdown.Both); MyClientSocket.Close(); } } } private static byte[] result = new byte[1024 * 1024]; static Socket ServerSocket = new Socket(AddressFamily.InterNetwork,SocketType.Stream,ProtocolType.Tcp); static void Main(String[] args) { try { int Port = 8222; IPAddress IP = IPAddress.Parse("127.0.0.1"); ServerSocket.Bind(new IPEndPoint(IP, Port)); ServerSocket.Listen(10); Console.WriteLine("启动监听{0}成功",ServerSocket.LocalEndPoint.ToString()); Thread thread = new Thread(ListenClientConnect); thread.Start(); Thread.Sleep(2000); } catch(Exception ex) { throw ex; } } } }
一对多:
服务端代码:
using System; using System.Collections.Generic; using System.Net; using System.Net.Sockets; using System.Threading; using System.Text; using System.Linq; namespace Server { class Program { public static void ListenConnection() { Socket ConnectionSocket = null; while(true) { try { ConnectionSocket = ServerSocket.Accept(); } catch(Exception ex) { Console.WriteLine("监听套接字异常{0}",ex.Message); break; } //获取客户端端口号和IP IPAddress ClientIP=(ConnectionSocket.RemoteEndPoint as IPEndPoint).Address; int ClientPort = (ConnectionSocket.RemoteEndPoint as IPEndPoint).Port; string SendMessage = "连接服务器成功\r\n" + "本地IP:" + ClientIP + ",本地端口:" + ClientPort.ToString(); //Console.WriteLine(SendMessage); ConnectionSocket.Send(Encoding.UTF8.GetBytes(SendMessage)); string remotePoint = ConnectionSocket.RemoteEndPoint.ToString(); Console.WriteLine("成功与客户端{0}建立连接!\t\n", remotePoint); ClientInformation.Add(remotePoint, ConnectionSocket); Thread thread = new Thread(ReceiveMessage); thread.IsBackground = true; thread.Start(ConnectionSocket); } } public static void ReceiveMessage(Object SocketClient) { Socket ReceiveSocket = (Socket)SocketClient; while(true) { byte[] result = new byte[1024 * 1024]; try { IPAddress ClientIP = (ReceiveSocket.RemoteEndPoint as IPEndPoint).Address; int ClientPort = (ReceiveSocket.RemoteEndPoint as IPEndPoint).Port; int ReceiveLength = ReceiveSocket.Receive(result); string ReceiveMessage = Encoding.UTF8.GetString(result, 0, ReceiveLength); Console.WriteLine("接收客户端:" + ReceiveSocket.RemoteEndPoint.ToString()+ "时间:"+DateTime.Now.ToString()+"\r\n"+"消息:"+ReceiveMessage+"\r\n\n"); foreach(string key in new List<string>(ClientInformation.Keys)) { string s = ReceiveSocket.RemoteEndPoint.ToString(); if(key!=s) { Socket socket = ClientInformation[key]; Console.WriteLine("向客户端{0}发送消息:", key); socket.Send(Encoding.UTF8.GetBytes(ReceiveMessage)); } } //Console.WriteLine("向客户端{0}发送消息:", ReceiveSocket.RemoteEndPoint.ToString()); //string sb = Console.ReadLine(); //ReceiveSocket.Send(Encoding.UTF8.GetBytes(sb)); } catch(Exception ex) { Console.WriteLine("监听出现异常!!!"); Console.WriteLine("客户端" + ReceiveSocket.RemoteEndPoint + "已经连接中断" + "\r\n" + ex.Message + "\r\n" + ex.StackTrace + "\r\n"); foreach(string key in new List<string>(ClientInformation.Keys)) { string s = ReceiveSocket.RemoteEndPoint.ToString(); if (key.Equals(s)) { ClientInformation.Remove(key); } } ReceiveSocket.Shutdown(SocketShutdown.Both); ReceiveSocket.Close(); break; } } } //private static byte[] result = new byte[1024]; //List<Socket> list = new List<Socket>(); static Dictionary<string, Socket> ClientInformation = new Dictionary<string, Socket> { }; static Socket ServerSocket = new Socket(AddressFamily.InterNetwork, SocketType.Stream, ProtocolType.Tcp); static void Main(String[] args) { try { int Port = 8333; IPAddress IP = IPAddress.Parse("127.0.0.1"); ServerSocket.Bind(new IPEndPoint(IP, Port)); ServerSocket.Listen(10); Console.WriteLine("启动监听成功!"); Console.WriteLine("监听本地{0}成功", ServerSocket.LocalEndPoint.ToString()); Thread ThreadListen = new Thread(ListenConnection); ThreadListen.IsBackground = true; ThreadListen.Start(); Thread.Sleep(2000); } catch(Exception ex) { Console.WriteLine("监听异常!!!"); ServerSocket.Shutdown(SocketShutdown.Both); ServerSocket.Close(); } Console.ReadKey(); Console.WriteLine("监听完毕,按任意键退出!"); } } }客户端代码:
using System; using System.Net; using System.Net.Sockets; using System.Threading; using System.Text; namespace Client { class Problem { private static byte[] result = new byte[1024 * 1024]; static Socket ClientSocket = new Socket(AddressFamily.InterNetwork,SocketType.Stream,ProtocolType.Tcp); public static void ReceiveMessage() { while(true) { try { int ReceiveLength = ClientSocket.Receive(result); Console.WriteLine("接收服务器消息:{0}", Encoding.UTF8.GetString(result, 0, ReceiveLength)); } catch(Exception ex) { Console.WriteLine("出现异常了!!!"); Console.WriteLine(ex.Message); ClientSocket.Shutdown(SocketShutdown.Both); ClientSocket.Close(); break; } } } static void Main(string[] args) { int Port = 8333; IPAddress IP = IPAddress.Parse("127.0.0.1"); try { ClientSocket.Connect(new IPEndPoint(IP,Port)); Thread thread = new Thread(ReceiveMessage); thread.Start(); Thread.Sleep(2000); } catch(Exception ex) { Console.WriteLine("连接服务器失败,按回车键退出!"); return; } Console.WriteLine("连接服务器成功!!!"); //int ReceiveLength = ClientSocket.Receive(result); //Console.WriteLine("接收服务器消息:{0}", Encoding.UTF8.GetString(result, 0, ReceiveLength)); while (true) { try { Thread.Sleep(2000); Console.WriteLine("向服务器发送消息:"); string sb = Console.ReadLine(); string Client = ClientSocket.RemoteEndPoint.ToString(); string SendMessage = "接收客户端" + Client + "消息:" + DateTime.Now + "\n" + sb; ClientSocket.Send(Encoding.ASCII.GetBytes(sb)); } catch(Exception ex) { ClientSocket.Shutdown(SocketShutdown.Both); ClientSocket.Close(); break; } } Console.WriteLine("消息发送完毕!!!"); Console.ReadLine(); } } }
下面是一对多的使用窗体界面显示的代码以及显示效果:
客户端代码:
using System; using System.Collections.Generic; using System.ComponentModel; using System.Data; using System.Drawing; using System.Linq; using System.Text; using System.Threading.Tasks; using System.Windows.Forms; using System.Net.Sockets; using System.Net; using System.Threading; using System.IO; namespace ClientForm { public partial class Form1 : Form { private byte[] result = new byte[1024 * 1024]; private Socket ClientSocket = new Socket(AddressFamily.InterNetwork, SocketType.Stream, ProtocolType.Tcp); public Form1() { InitializeComponent(); TextBox.CheckForIllegalCrossThreadCalls = false; } private void Form1_Load(object sender, EventArgs e) { ; } private void textBox1_TextChanged(object sender, EventArgs e)//输入消息 { //; string str = Console.ReadLine(); textBox1.Text += str; } private void textBox2_TextChanged(object sender, EventArgs e)//ip { ; } private void textBox3_TextChanged(object sender, EventArgs e)//port { ; } private void button1_Click(object sender, EventArgs e)//发送消息 { try { //Thread.Sleep(2000); richTextBox1.Text += "向服务器发送消息:\r\n"; richTextBox1.Text += textBox1.Text + "\r\n"; string sb = textBox1.Text; string Client = ClientSocket.RemoteEndPoint.ToString(); string SendMessage = "接收客户端" + Client + "消息:" + DateTime.Now + "\r\n" + sb + "\r\n"; ClientSocket.Send(Encoding.UTF8.GetBytes(sb)); textBox1.Clear(); } catch (Exception ex) { richTextBox1.Text += "服务器可能已经关闭!\r\n"; ClientSocket.Shutdown(SocketShutdown.Both); ClientSocket.Close(); } } private void button2_Click(object sender, EventArgs e)//连接服务器 { int Port = Convert.ToInt32(textBox3.Text); IPAddress IP = IPAddress.Parse((string)textBox2.Text); try { ClientSocket.Connect(new IPEndPoint(IP, Port)); richTextBox2.Text += "连接服务器成功!\r\n"; Thread thread = new Thread(ReceiveMessage); thread.IsBackground = true; thread.Start(); } catch (Exception ex) { richTextBox2.Text += "连接服务器失败!\r\n"; return; } } private void label1_Click(object sender, EventArgs e) { ; } private void label2_Click(object sender, EventArgs e) { ; } private void richTextBox1_TextChanged(object sender, EventArgs e)//显示发送的消息 { ; } private void richTextBox2_TextChanged(object sender, EventArgs e)//显示接收的消息 { ; } private void ReceiveMessage() { while (true) { try { int ReceiveLength = ClientSocket.Receive(result); richTextBox2.Text += "接收服务器消息:\r\n"; string str = Encoding.UTF8.GetString(result, 0, ReceiveLength)+"\r\n"; richTextBox2.Text += str; } catch (Exception ex) { richTextBox2.Text += "接收消息失败!\r\n"; ClientSocket.Shutdown(SocketShutdown.Both); ClientSocket.Close(); break; } } } } }
服务端代码:
using System; using System.Collections.Generic; using System.ComponentModel; using System.Data; using System.Drawing; using System.Linq; using System.Text; using System.Threading.Tasks; using System.Windows.Forms; using System.Net.Sockets; using System.Net; using System.Threading; using System.IO; using System.Threading; namespace ServerForm { public partial class Form1 : Form { private byte[] result = new byte[1024 * 1024]; private Socket ServerSocket = new Socket(AddressFamily.InterNetwork, SocketType.Stream, ProtocolType.Tcp); private Dictionary<string, Socket> ClientInformation = new Dictionary<string, Socket> { }; public Form1() { InitializeComponent(); TextBox.CheckForIllegalCrossThreadCalls = false; //在多线程程序中,新创建的线程不能访问UI线程创建的窗口控件 //如果需要访问窗口控件则可以如此设置 } private void label1_Click(object sender, EventArgs e)//ip { } private void label2_Click(object sender, EventArgs e)//Port { } private void label3_Click(object sender, EventArgs e)//在线列表 { } private void richTextBox1_TextChanged(object sender, EventArgs e)//显示客户端之间/客户端消息 { } private void richTextBox2_TextChanged(object sender, EventArgs e)//显示连接成功或者掉线的客户端 { } private void richTextBox3_TextChanged(object sender, EventArgs e)//显示在线列表 { } private void textBox1_TextChanged(object sender, EventArgs e)//IP { } private void textBox2_TextChanged(object sender, EventArgs e)//Port { } private void button1_Click(object sender, EventArgs e)//启动服务 { try { int Port = Convert.ToInt32(textBox2.Text); IPAddress IP = IPAddress.Parse((string)textBox1.Text); ServerSocket.Bind(new IPEndPoint(IP, Port)); ServerSocket.Listen(10); richTextBox2.Text += "启动监听成功!\r\n"; richTextBox2.Text += "监听本地" + ServerSocket.LocalEndPoint.ToString() + "成功\r\n"; Thread ThreadListen = new Thread(ListenConnection); ThreadListen.IsBackground = true; ThreadListen.Start(); Thread.Sleep(2000); } catch(Exception ex) { richTextBox2.Text += "监听异常!!!\r\n"; ServerSocket.Shutdown(SocketShutdown.Both); ServerSocket.Close(); } } private void ListenConnection() { Socket ConnectionSocket = null; while (true) { try { ConnectionSocket = ServerSocket.Accept(); } catch (Exception ex) { richTextBox2.Text += "监听套接字异常" + ex.Message; //Console.WriteLine("监听套接字异常{0}", ex.Message); break; } //获取客户端端口号和IP IPAddress ClientIP = (ConnectionSocket.RemoteEndPoint as IPEndPoint).Address; int ClientPort = (ConnectionSocket.RemoteEndPoint as IPEndPoint).Port; string SendMessage = "本地IP:" + ClientIP + ",本地端口:" + ClientPort.ToString(); ConnectionSocket.Send(Encoding.UTF8.GetBytes(SendMessage)); string remotePoint = ConnectionSocket.RemoteEndPoint.ToString(); richTextBox2.Text += "成功与客户端" + remotePoint + "建立连接\r\n"; richTextBox3.Text += DateTime.Now+":"+remotePoint + "\r\n"; ClientInformation.Add(remotePoint, ConnectionSocket); Thread thread = new Thread(ReceiveMessage); thread.IsBackground = true; thread.Start(ConnectionSocket); } } private void ReceiveMessage(Object SocketClient) { Socket ReceiveSocket = (Socket)SocketClient; while (true) { byte[] result = new byte[1024 * 1024]; try { IPAddress ClientIP = (ReceiveSocket.RemoteEndPoint as IPEndPoint).Address; int ClientPort = (ReceiveSocket.RemoteEndPoint as IPEndPoint).Port; int ReceiveLength = ReceiveSocket.Receive(result); string str = ReceiveSocket.RemoteEndPoint.ToString(); string ReceiveMessage = Encoding.UTF8.GetString(result, 0, ReceiveLength); richTextBox1.Text+= "接收客户端:" + ReceiveSocket.RemoteEndPoint.ToString() + "时间:" + DateTime.Now.ToString() + "\r\n" + "消息:" + ReceiveMessage + "\r\n"; if (ClientInformation.Count == 1) continue;//只有一个客户端 List<string> test = new List<string>(ClientInformation.Keys); for (int i = 0; i < ClientInformation.Count; i++) { Socket socket = ClientInformation[test[i]]; string s = ReceiveSocket.RemoteEndPoint.ToString(); if (test[i] != s) { richTextBox1.Text += DateTime.Now + "\r\n" + "客户端" + str + "向客户端" + test[i] + "发送消息:" + ReceiveMessage; string ReceiveMessage1 = DateTime.Now + "\r\n" + "客户端" + str + "向您发送消息:" + ReceiveMessage; socket.Send(Encoding.UTF8.GetBytes(ReceiveMessage1)); } } } catch (Exception ex) { richTextBox2.Text += "监听出现异常!\r\n"; richTextBox2.Text += "客户端" + ReceiveSocket.RemoteEndPoint + "已经连接中断" + "\r\n" + ex.Message + "\r\n" + ex.StackTrace + "\r\n"; string s = ReceiveSocket.RemoteEndPoint.ToString(); ClientInformation.Remove(s); ReceiveSocket.Shutdown(SocketShutdown.Both); ReceiveSocket.Close(); break; } } } } }界面效果:
注:我这里在线列表显示的是所有连接过服务器的客户端,对于可能出现的乱码问题,将相应的ASCII改为UTF-8即可
新手我建议可以先看这两位博主的文章:
https://www.cnblogs.com/vaevvaev/p/6865968.html
https://www.cnblogs.com/yy3b2007com/p/7476458.html
客户端:
服务器: