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循环,执行了之后的代码。

02-11 13:48