服务器/客户端未发送所有字节(TCP 套接字)

Posted

技术标签:

【中文标题】服务器/客户端未发送所有字节(TCP 套接字)【英文标题】:Server/Client not sending all the bytes (TCP Sockets) 【发布时间】:2015-08-13 13:26:42 【问题描述】:

我构建了一个通过 TCP 套接字发送字符串的应用程序。它的工作原理是这样的: 服务器等待连接->当有人连接时,如果字符串包含<EOG,它会读取字符串,否则它会停止发送响应。 客户端的工作方式如下: 客户端尝试连接到服务器 -> 发送字符串 -> 从服务器读取响应,如果 respod 包含 <EOG> 它会停止。 它发送我告诉它的每个字符串,但是当我发送一个包含 <EOG> 的字符串时,它只发送 5 个字节并停止。这是服务器代码:

 static void Main(string[] args)
        
            string messageFromClient = null;
            Socket listener = new Socket(AddressFamily.InterNetwork, SocketType.Stream, ProtocolType.Tcp);
            byte[] bytes = new byte[1024];
            IPAddress ipAdress = IPAddress.Parse(LocalIPAddress());
            const int PORT = 13000;
            IPEndPoint localEndPoint = new IPEndPoint(ipAdress, PORT);
            try
            
                listener.Bind(localEndPoint);
                listener.Listen(10);
                Console.WriteLine("Wating for a connection..");
                Socket handler = listener.Accept();
                Console.WriteLine("Got a connection from 0", handler.RemoteEndPoint.ToString());
                while (true)
                
                    while (true)
                    

                        bytes = new byte[1024];
                        int bytesRec = handler.Receive(bytes);
                        messageFromClient += Encoding.ASCII.GetString(bytes, 0, bytesRec);
                        if (messageFromClient.IndexOf("<Stop>") > -1) break;
                    
                    if (messageFromClient.Contains("<EOG>"))
                    
                        Console.WriteLine("Text recived: 0",messageFromClient.Replace("<Stop>",""));
                        handler.Shutdown(SocketShutdown.Both);
                        handler.Close();
                        Console.WriteLine("Handler closed.");
                        return;
                    
                    Console.WriteLine("Text recived: 0", messageFromClient.Replace("<Stop>", ""));
                    messageFromClient = null;
                    string readInput = Console.ReadLine() + "<Stop>";
                    byte[] messageToClient = Encoding.ASCII.GetBytes(readInput);
                    handler.Send(messageToClient);
                    if (readInput.Contains("<EOG>"))
                    
                        handler.Shutdown(SocketShutdown.Both);
                        handler.Close();
                        Console.WriteLine("Handler closed.");
                        return;
                    
                
            
            catch (SocketException se)
            
                Console.WriteLine(se.ToString());
            
            catch (ArgumentNullException ane)
            
                Console.WriteLine(ane.ToString());
            

        
        public static string LocalIPAddress()
        
            IPHostEntry host;
            string localIP = "";
            host = Dns.GetHostEntry(Dns.GetHostName());
            foreach (IPAddress ip in host.AddressList)
            
                if (ip.AddressFamily == AddressFamily.InterNetwork)
                
                    localIP = ip.ToString();
                    break;
                
            
            return localIP;
        

这是客户端代码:

static void Main(string[] args)
        
            IPAddress ipAdress = IPAddress.Parse(LocalIPAddress());
            byte[] bytes = new byte[1024];
            const int PORT = 13000;
            IPEndPoint remoteEP = new IPEndPoint(ipAdress, PORT);
            Socket sender = new Socket(AddressFamily.InterNetwork, SocketType.Stream, ProtocolType.Tcp);
            string messageFromServer = null;
            try
            
                sender.Connect(remoteEP);
                Console.WriteLine("Connected to 0",sender.RemoteEndPoint.ToString());
                while (true)
                
                    string readInput = Console.ReadLine() + "<Stop>";
                    byte[] messageToServer = Encoding.ASCII.GetBytes(readInput);
                    if (readInput.Contains("<EOG>"))
                    
                        messageToServer = Encoding.ASCII.GetBytes("<EOG>");
                        int bytesSentEnd = sender.Send(messageToServer);
                        Console.WriteLine("Sent 0 bytes to the server", bytesSentEnd);
                        sender.Shutdown(SocketShutdown.Both);
                        sender.Close();
                        Console.WriteLine("Sender closed.");
                        return;
                    
                    int bytesSent = sender.Send(messageToServer);
                    Console.WriteLine("Sent 0 bytes to the server", bytesSent);
                    while (true)
                    
                        int bytesRec = sender.Receive(bytes);
                        messageFromServer += Encoding.ASCII.GetString(bytes, 0, bytesRec);
                        if (messageFromServer.IndexOf("<Stop>") > -1) break;
                        if (messageFromServer.Contains("<EOG>"))
                        
                            sender.Shutdown(SocketShutdown.Both);
                            sender.Close();
                            Console.WriteLine("Sender closed.");
                            return;
                        
                    
                    Console.WriteLine("Message from server: 0", messageFromServer.Replace("<Stop>",""));
                    messageFromServer = null;
                
            
            catch (SocketException se)
            
                Console.WriteLine("Sokcet Exception: 0", se.ToString());
            
            catch (ArgumentNullException ane)
            
                Console.WriteLine("Argument Null Exception: 0", ane.ToString());
            
            catch (Exception ex)
            
                Console.WriteLine("Unexpected excetption: 0",ex.ToString());
            
        
        public static string LocalIPAddress()
        
            IPHostEntry host;
            string localIP = "";
            host = Dns.GetHostEntry(Dns.GetHostName());
            foreach (IPAddress ip in host.AddressList)
            
                if (ip.AddressFamily == AddressFamily.InterNetwork)
                
                    localIP = ip.ToString();
                    break;
                
            
            return localIP;
        

如果用户输入类似“hi &lt;EOG&gt; “它只发送 5 个字节并自行停止。现在我不希望这种情况发生,我希望它发送整个消息,然后才停止自身。此外,如果消息包含“&lt;EOG&gt;”,那么接收方不会接收任何内容. 我怎样才能让它发送整个消息然后才关闭?

【问题讨论】:

handler.Receive(bytes) 有一个错误。它会覆盖先前从先前循环迭代中读取的数据。修复它,更新代码并报告是否解决了问题。 它发送的正是你告诉它发送的内容:messageToServer = Encoding.ASCII.GetBytes(""); 【参考方案1】:

按照 jdweng 告诉我的操作,以及对代码进行更多调整,我能够解决此问题。如果有人想要,这里是工作代码:服务器端:

static void Main(string[] args)
    

        string messageFromClient = null;
        Socket listener = new Socket(AddressFamily.InterNetwork, SocketType.Stream, ProtocolType.Tcp);
        byte[] bytes = new byte[1024];
        IPAddress ipAdress = IPAddress.Parse(LocalIPAddress());
        const int PORT = 13000;
        IPEndPoint localEndPoint = new IPEndPoint(ipAdress, PORT);
        try
        
            listener.Bind(localEndPoint);
            listener.Listen(10);
            Console.WriteLine("Wating for a connection..");
            Socket handler = listener.Accept();
            Console.WriteLine("Got a connection from 0", handler.RemoteEndPoint.ToString());
            while (true)
            
                while (true)
                

                    bytes = new byte[1024];
                    int bytesRec = handler.Receive(bytes);
                    messageFromClient += Encoding.ASCII.GetString(bytes, 0, bytesRec);
                    if (messageFromClient.IndexOf("<Stop>") > -1) break;
                
                if (messageFromClient.Contains("<EOG>"))
                
                    Console.WriteLine("Text recived: 0", messageFromClient.Replace("<Stop>", ""));
                    handler.Shutdown(SocketShutdown.Both);
                    handler.Close();
                    Console.WriteLine("Handler closed.");
                    return;
                
                Console.WriteLine("Text recived: 0", messageFromClient.Replace("<Stop>", ""));
                messageFromClient = null;
                string readInput = Console.ReadLine() + "<Stop>";
                byte[] messageToClient = Encoding.ASCII.GetBytes(readInput);
                handler.Send(messageToClient);
                if (readInput.Contains("<EOG>"))
                
                    handler.Shutdown(SocketShutdown.Both);
                    handler.Close();
                    Console.WriteLine("Handler closed.");
                    return;
                
            
        
        catch (SocketException se)
        
            Console.WriteLine(se.ToString());
        
        catch (ArgumentNullException ane)
        
            Console.WriteLine(ane.ToString());
        

    
    public static string LocalIPAddress()
    
        IPHostEntry host;
        string localIP = "";
        host = Dns.GetHostEntry(Dns.GetHostName());
        foreach (IPAddress ip in host.AddressList)
        
            if (ip.AddressFamily == AddressFamily.InterNetwork)
            
                localIP = ip.ToString();
                break;
            
        
        return localIP;
    

客户端:

static void Main(string[] args)
    
        IPAddress ipAdress = IPAddress.Parse(LocalIPAddress());
        byte[] bytes = new byte[1024];
        const int PORT = 13000;
        IPEndPoint remoteEP = new IPEndPoint(ipAdress, PORT);
        Socket sender = new Socket(AddressFamily.InterNetwork, SocketType.Stream, ProtocolType.Tcp);
        string messageFromServer = null;
        try
        
            sender.Connect(remoteEP);
            Console.WriteLine("Connected to 0", sender.RemoteEndPoint.ToString());
            while (true)
            
                string readInput = Console.ReadLine() + "<Stop>";
                byte[] messageToServer = Encoding.ASCII.GetBytes(readInput);
                if (readInput.Contains("<EOG>"))
                
                    int bytesSentEnd = sender.Send(messageToServer);
                    Console.WriteLine("Sent 0 bytes to the server", bytesSentEnd);
                    sender.Shutdown(SocketShutdown.Both);
                    sender.Close();
                    Console.WriteLine("Sender closed.");
                    return;
                
                int bytesSent = sender.Send(messageToServer);
                Console.WriteLine("Sent 0 bytes to the server", bytesSent);
                while (true)
                
                    int bytesRec = sender.Receive(bytes);
                    messageFromServer += Encoding.ASCII.GetString(bytes, 0, bytesRec);
                    if (messageFromServer.Contains("<EOG>"))
                    
                        sender.Shutdown(SocketShutdown.Both);
                        sender.Close();
                        Console.WriteLine("Sender closed.");
                        return;
                    
                    if (messageFromServer.IndexOf("<Stop>") > -1) break;
                
                Console.WriteLine("Message from server: 0", messageFromServer.Replace("<Stop>", ""));
                messageFromServer = null;
            
        

        catch (SocketException se)
        
            Console.WriteLine("Sokcet Exception: 0", se.ToString());
        
        catch (ArgumentNullException ane)
        
            Console.WriteLine("Argument Null Exception: 0", ane.ToString());
        
        catch (Exception ex)
        
            Console.WriteLine("Unexpected excetption: 0", ex.ToString());
        
    
    public static string LocalIPAddress()
    
        IPHostEntry host;
        string localIP = "";
        host = Dns.GetHostEntry(Dns.GetHostName());
        foreach (IPAddress ip in host.AddressList)
        
            if (ip.AddressFamily == AddressFamily.InterNetwork)
            
                localIP = ip.ToString();
                break;
            
        
        return localIP;
    

希望这能以某种方式帮助某人:)

【讨论】:

以上是关于服务器/客户端未发送所有字节(TCP 套接字)的主要内容,如果未能解决你的问题,请参考以下文章

在 TCP 套接字程序中,客户端发送一些数据,但服务器需要多次读取。为啥?

TCP 套接字:recv() 没有收到我的完整数据

C - 填充 TCP 套接字发送缓冲区

C中的服务器/套接字编程:数据未正确发送/接收?

套接字编程/通过无线发送二进制图像数据

一次从一个 TCP 套接字发送超过 32768 个字节到另一个