C#,Socket通讯原理,附加源码解释(Socket服务端和客户端)

1、先启动服务端 IP和端口都为服务端
2、客户端连接到服务端 IP和端口都为服务端
3、客户端发送信息到服务端

源码下载地址: https://pan.baidu.com/s/1sjjdJXeA9xhGCJ_OlITtjQ?pwd=fn1a 提取码: fn1a

以下是原理图

以下是Socket服务端核心代码

//原创来自 http://www.luofenming.com/show.aspx?id=ART2018120700001
/// <summary>
/// 创建Scoket 服务端
/// </summary>
/// <param name="IP"></param>
/// <param name="prot"></param>
/// <returns></returns>
public Socket CreateSocket(string IP, string prot)
{
    //定义一个套接字用于监听客户端发来的信息  包含3个参数(IP4寻址协议,流式连接,TCP协议)
    Socket socketWatch = new Socket(AddressFamily.InterNetwork, SocketType.Stream, ProtocolType.Tcp);
    //发送信息 需要1个IP地址和端口号
    IPAddress ipaddress = IPAddress.Parse(IP); //获取文本框输入的IP地址
    //将IP地址和端口号绑定到网络节点endpoint上 
    IPEndPoint endpoint = new IPEndPoint(ipaddress, int.Parse(prot)); //获取文本框上输入的端口号
    //套接字点听绑定网络端点
    socketWatch.Bind(endpoint);
    //将套接字的监听队列长度设置为20
    socketWatch.Listen(20);
    return socketWatch;
}

/// <summary>
/// 创建一个负责监听客户端的线程  并启动
/// </summary>
/// <returns></returns>
public void CreateThread(Socket socket)
{
    //创建一个负责监听客户端的线程 
    Thread threadWatch = new Thread(new ParameterizedThreadStart(WatchConnecting));
    //将窗体线程设置为与后台同步
    threadWatch.IsBackground = true;
    //启动线程
    threadWatch.Start(socket);
}

/// <summary>
/// 持续不断监听客户端发来的请求, 用于不断获取客户端发送过来的连续数据信息
/// </summary>
private void WatchConnecting(object socket)
{
    Socket socketWatch = socket as Socket;
    while (true)
    {
        Socket socConnection = null;
        try
        {
            socConnection = socketWatch.Accept();
            //((IPEndPoint)socConnection.RemoteEndPoint).Address.ToString();//获取客户端IP
            //((IPEndPoint)socConnection.RemoteEndPoint).Port.ToString();//获取客户端端口
        }
        catch (Exception ex)
        {
            break;//提示套接字监听异常  ex.Message   
        }
        //创建通信线程 
        ParameterizedThreadStart pts = new ParameterizedThreadStart(ServerRecMsg);
        Thread thr = new Thread(pts);
        thr.IsBackground = true;
        //启动线程 
        thr.Start(socConnection);
    }
}

/// <summary>
/// 接收客户端发来的信息
/// </summary>
private void ServerRecMsg(object socketClientPara)
{
    Socket socketServer = socketClientPara as Socket;
    int ReceiveBufferSize = 8 * 1024;
    while (true)
    {
        int firstReceived = 0;
        byte[] buffer = new byte[ReceiveBufferSize];
        try
        {
            List<byte> ls = new List<byte>();
            //获取接收的数据,并存入内存缓冲区  返回一个字节数组的长度
            if (socketServer != null) firstReceived = socketServer.Receive(buffer);

            if (firstReceived > 0) //接受到的长度大于0 说明有信息或文件传来
            {
                ls.AddRange(buffer.Skip(0).Take(firstReceived));

                //对接收数据进行逻辑判断 回复客户端需要的数据
                string msg = "接收成功" + DateTime.Now.ToString("yyyy-MM-dd HH:mm:ss") + "\r\n";
                byte[] datas = System.Text.Encoding.UTF8.GetBytes(msg);
                socketServer.Send(datas);//小数据可以一次性发送  如果大数据要分端发送 用while 循环
            }
        }
        catch (Exception ex)
        {
            break;  //捕获异常信息 ex.Message
        }
    }
}

//启动服务端
private void button1_Click(object sender, EventArgs e)
{
    //textBox1.Text 为服务端IP  textBox2.Text 为服务端端口
    Socket testSocket = CreateSocket(textBox1.Text, textBox2.Text);
    CreateThread(testSocket);
}

以下是客户端核心代码

//原创来自 http://www.luofenming.com/show.aspx?id=ART2018120700001
/// <summary>
/// 创建Scoket 客户端
/// </summary>
/// <param name="IP"></param>
/// <param name="prot"></param>
/// <returns></returns>
public Socket CreateSocket(string IP, string prot)
{
    //定义一个套接字用于监听客户端发来的信息  包含3个参数(IP4寻址协议,流式连接,TCP协议)
    Socket socketClient = new Socket(AddressFamily.InterNetwork, SocketType.Stream, ProtocolType.Tcp);
    //发送信息 需要1个IP地址和端口号
    IPAddress ipaddress = IPAddress.Parse(IP); //获取文本框输入的IP地址
    //将IP地址和端口号绑定到网络节点endpoint上 
    IPEndPoint endpoint = new IPEndPoint(ipaddress, int.Parse(prot)); //获取文本框上输入的端口号
    //向指定的ip和端口号的服务端发送连接请求 用的方法是Connect 不是Bind
    socketClient.Connect(endpoint);
    return socketClient;
}
/// <summary>
/// 创建一个接收服务端发来信息的  线程并启动
/// </summary>
/// <param name="socket"></param>
private void CreateThread(Socket socket)
{
    //创建一个新线程 用于监听服务端发来的信息
    Thread threadClient = new Thread(RecMsg);
    //将窗体线程设置为与后台同步
    threadClient.IsBackground = true;
    //启动线程
    threadClient.Start(socket);
}

/// <summary>
/// 接受服务端发来信息的方法
/// </summary>
private void RecMsg(object socket)
{
    Socket socketClient = socket as Socket;
    int SendBufferSize = 2 * 1024;
    while (true) //持续监听服务端发来的消息
    {
        int length = 0;
        byte[] buffer = new byte[SendBufferSize];
        try
        {
            length = socketClient.Receive(buffer);
        }
        catch (Exception ex)
        {
            break;
        }
        //将套接字获取到的字节数组转换为人可以看懂的字符串
        string strRecMsg = Encoding.UTF8.GetString(buffer, 0, length);
    }
}
Socket socket;

/// <summary>
/// 连接服务端
/// </summary>
/// <param name="sender"></param>
/// <param name="e"></param>
private void button1_Click(object sender, EventArgs e)
{
    //textBox1.Text 为服务端IP  textBox2.Text 为服务端端口
    socket = CreateSocket(textBox1.Text, textBox2.Text);
    CreateThread(socket);
}

/// <summary>
/// 发送信息到服务端
/// </summary>
/// <param name="sender"></param>
/// <param name="e"></param>
private void button2_Click(object sender, EventArgs e)
{
    if (socket != null && socket.Connected)
    {
        socket.Send(new byte[] { 0x11, 0x22, 0x33, 0x44, 0x55 });
    }
}