1、创建控制台程序SocketTcpServer,注意引用using System.Net; using System.Net.Sockets;
namespace SocketTcpServer { class Program { static List<Client> clientList = new List<Client>();//多个客户端的集合 static void Main(string[] args) { //1、创建socket Socket tcpServer = new Socket(AddressFamily.InterNetwork, SocketType.Stream, ProtocolType.Tcp);//地址族、套接字类型、协议 //2、绑定本地ip和端口号(一个网卡就有一个ip,电脑可能有多个ip) tcpServer.Bind(new IPEndPoint(IPAddress.Parse("192.168.3.3"), 2000)); //3、开始监听 tcpServer.Listen(10);//最大连接数 Console.WriteLine("服务器启动成功!"); while (true) //实现与多个客户端连接 { Socket clientSocket = tcpServer.Accept();//暂停当前线程,直到有客户端连接之后,才进行之后的代码 Console.WriteLine("有客户端连接成功!"); //自定义类 Client client = new Client(clientSocket);//把与每个客户端通信的逻辑(收发消息)放到Client类里进行处理 clientList.Add(client);//把连接的客户端添加到集合里 } } } }
新建类Client.cs,用来与客户端做通信(具体的交互逻辑)。注意引用using System.Net; using System.Net.Sockets;using System.Threading;
namespace SocketTcpServer { /// <summary> /// 与客户端做通信 /// </summary> class Client { private Socket clientSocket; private Thread t;//控制信息接收与否 private byte[] data = new byte[1024];//收信息需要开辟内存 public Client(Socket s)//构造方法 { clientSocket = s; //启动一个线程,监听来自客户端的信息 t = new Thread(ReceiveMessage); t.Start(); } private void ReceiveMessage() { while (true)//一直接收客户端的信息 { //接收信息之前,判断socket的连接是否断开(断开会一直接收空字符) if (clientSocket.Poll(10, SelectMode.SelectRead))//如果连接已关闭,返回true,频率10ms { break; //跳出循环,终止线程 } int length = clientSocket.Receive(data);//接收的是字节数组 string message = Encoding.UTF8.GetString(data, 0, length);//展示的是字符串 Console.WriteLine("收到了消息:" + message); } } } }
2、创建WinForm窗体程序SocketTcpClient_WinForm(界面如动图所示),注意引用using System.Net; using System.Net.Sockets;
namespace SocketTcpClient_WinForm { public partial class Form1 : Form { public string ip = "192.168.3.3"; public int port = 2000; Socket clientSocket; //连接了远程主机的Socket private void ConnectToServer()//连接服务器 { //1、创建socket clientSocket = new Socket(AddressFamily.InterNetwork,SocketType.Stream,ProtocolType.Tcp); //2、连接远程主机的IP和端口号 clientSocket.Connect(new IPEndPoint(IPAddress.Parse(ip), port)); } private void SendMessage(string message)//发送信息 { byte[] data = Encoding.UTF8.GetBytes(message); clientSocket.Send(data);//发送的是字节数组 } public Form1() { InitializeComponent(); ConnectToServer();//连接服务器 } private void button1_Click(object sender, EventArgs e) { SendMessage(textBox1.Text);//发送信息 } private void Form1_FormClosed(object sender, FormClosedEventArgs e) { clientSocket.Close();//关闭连接。客户端必须有此句代码,否则服务器会提示错误或一直接收空字符。 } } }
3、先启动服务器,再启动客户端。
【注意一个现象】先启动服务器,再启动客户端。直接关闭客户端,还是会发送一个空字符。即break没有立刻跳出while循环,执行了之后的代码。