Bootstrap

C#建立TCP/IP连接

C#建立TCP/IP连接

在C/S模式下做网络信号传输,使用TCP/IP协议是首选。
其传输机制:
首先服务端与客户端建立套接字(socket)连接,建立完套接字后,服务端与客户端通过套接字进行数据传输。通常服务端和客户端需要各开启一个线程进行数据的接收。

1.构建连接

首先服务端开启套接字监听服务,然后客户端根据服务器的IP、端口进行连接。

1.1服务端开启套接字

Socket serverSocket = new Socket(AddressFamily.InterNetwork, SocketType.Stream,ProtocolType.Tcp);
serverSocket.Bind(new IPEndPoint(ip, myProt));  //绑定IP地址:端口  
serverSocket.Listen(10);//设定最多10个排队连接请求  

注意在绑定IP时serverSocket.Bind(new IPEndPoint(ip, myProt));如果使用127.0.0.1时,客户端连接服务端的IP也必须是127.0.0.1,即要求服务端、客户端都在本地才可以通联。因此,需要将服务器套接字绑定的IP改为对外的IP,如192.168.0.1;
获取对外IP的方法为

/// <summary>
   /// 获取本地IP
   /// </summary>
   /// <returns></returns>
   private string GetAddressIP()
   {
    string AddressIP = string.Empty;
    foreach (IPAddress _IPAddress in Dns.GetHostEntry(Dns.GetHostName()).AddressList)
    {
        if (_IPAddress.AddressFamily.ToString() == "InterNetwork")
        {
            AddressIP = _IPAddress.ToString();
        }
    }
    return AddressIP;
   }

1.2开启监听客户端连接的线程

new Thread(ListenClientConnect).Start(this);
/// <summary>  
/// 监听客户端连接  
/// </summary>  
private static void ListenClientConnect(object server)
{
    Server myServer = (Server)server;
    myServer.clientSocket = serverSocket.Accept();//线程在此等待,直到有客户端连接后方继续执行
    myServer.clientSocket.Send(Encoding.UTF8.GetBytes("连接成功"));
    Thread receiveThread = new Thread(ReceiveMessage);//启动接收信息线程
    receiveThread.Start(server);
}

当serverSocket.Accept()执行后就完成了套接字的建立,就可以发送消息了。

1.3客户端建立与服务端的连接

客户端也定义一个套接字 clientSocket,再调用其connect方法与服务端连接。

    public bool createConn()
    {     
        try
        {
            IPAddress ip = IPAddress.Parse(textBox_serverIp.Text);
            clientSocket = new Socket(AddressFamily.InterNetwork, SocketType.Stream, ProtocolType.Tcp);
            int connPort = Int16.Parse(textBox_serverPort.Text);
            clientSocket.Connect(new IPEndPoint(ip, connPort)); //配置服务器IP与端口  
            writeLog("连接服务器成功");
            button_createConn.Text = "断开连接";
            //开启监听线程
            receiveThread = new Thread(receiveMsg);
            receiveThread.Start(this);
        }
            catch (Exception e)
        {
            writeLog("连接服务器失败" + e.ToString());
            return false;
        }
        return true;
    }

2.数据传输

2.1数据发送

服务端与客户端数据发送均是调用Socket进行传输。注意传输的数据需要进行编码Encoding.UTF8.GetBytes()

    /// <summary>
    /// 发送消息
    /// </summary>
    /// <param name="signal"></param>
    /// <returns></returns>
    private bool sendSignal(string signal)
    {
        if (clientSocket == null)
        {
            writeLog("发送失败,未连接客户端");
            return false;
        }
        try
        {
            clientSocket.Send(Encoding.UTF8.GetBytes(signal + "。"));
            return true;
        }
        catch (Exception e)
        {
            writeLog("发送失败" + e.ToString());
            clientSocket = null;
        }
        return false;
    }

2.2数据接收

数据的接收建议开启一个新的线程进行接收,接收是通过调用socket的Receive方法实现的。

 new Thread(receiveMsg).Start(this);
    /// <summary>
    /// 接受消息处理线程
    /// </summary>
    /// <param name="clientForm"></param>
    public static void receiveMsg(object clientForm)
    {
        Client myClient = (Client)clientForm;
        byte[] result = new byte[1024];
        while (true)
        {
            try
            {
                //通过clientSocket接收数据  
                int receiveLength = myClient.clientSocket.Receive(result);
                string resultStr = Encoding.UTF8.GetString(result, 0, receiveLength);
                myClient.writeLog(string.Format("接收服务器消息:{0}", resultStr));     
            }
            catch (Exception e)
            {
                myClient.writeLog("读取数据失败,服务器可能已经断开" + e.ToString());
                Thread.Sleep(300);
                myClient.closeConn();       
            }   
        }   
    }

3.关闭连接

想套接字发送关闭的信号后,将本地套接字关闭

    clientSocket.Shutdown(SocketShutdown.Both);
    myServer.clientSocket.Close();

4.点击下载例程

;