C#套接字。只能收到第一条消息

时间:2012-06-11 08:46:14

标签: c# sockets

我在弄清楚为什么我只从计算机上运行的服务器应用程序(LocalHost)收到一个回复​​时遇到了一些麻烦。我没有此服务器应用程序的源代码,但它是一个Java应用程序。发送的消息是xml结构,必须以EoT标记结束。

沟通:

  1. 客户端连接到服务器。
  2. 客户端向服务器发送消息。
  3. 服务器将收到的邮件发送给客户端。
  4. 客户端向服务器发送消息。
  5. 服务器发送传输结束字符。
  6. 客户端向服务器发送消息。
  7. 服务器发送传输结束字符。
  8. 这是我的客户端连接,发送和接收的方式:

    public bool ConnectSocket(string server, int port)
    {
    System.Net.IPHostEntry hostEntry = null;
    
        try
        {
            // Get host related information.
            hostEntry = System.Net.Dns.GetHostEntry(server);
        }
        catch (System.Exception ex)
        {
                return false;
        }
    
    
        // Loop through the AddressList to obtain the supported AddressFamily. This is to avoid
        // an exception that occurs when the host IP Address is not compatible with the address family
        // (typical in the IPv6 case).
        foreach (System.Net.IPAddress address in hostEntry.AddressList)
        {
                System.Net.IPEndPoint ipe = new System.Net.IPEndPoint(address, port);
                System.Net.Sockets.Socket tempSocket = new System.Net.Sockets.Socket(ipe.AddressFamily, System.Net.Sockets.SocketType.Stream, 
                                                                                     System.Net.Sockets.ProtocolType.Tcp);
                tempSocket.Connect(ipe);
    
                if (tempSocket.Connected)
                {
                    m_pSocket = tempSocket;
                    m_pSocket.NoDelay = true;
                    return true;
                }
                else
                    continue;
            }
            return false;
        }
    }
    
    public void Send(string message)
    {
        message += (char)4;//We add end of transmission character
        m_pSocket.Send(m_Encoding.GetBytes(message.ToCharArray()));
    }
    
    private void Recive()
    {
        byte[] tByte = new byte[1024];
        m_pSocket.Receive(tByte);
        string recivemessage = (m_Encoding.GetString(tByte));
    }
    

1 个答案:

答案 0 :(得分:3)

您的Receive代码看起来非常错误;你永远不应该假设数据包到达服务器发送消息的相同结构 - TCP只是一个流。所以:你必须捕获Receive的回报,看看你收到了多少字节。它可以是一条消息的一部分,一条完整的消息,多条完整的消息,或者一条消息的后半部分和下一条消息的前半部分。通常,您需要某种“框架”决策,这可能意味着“由LF字符拆分的消息”,或者可能意味着“每条消息的长度以网络字节顺序整数为前缀,4个字节”。这通常意味着您需要缓冲,直到您有一个完整的帧,担心作为下一帧的一部分的缓冲区末尾的备用数据。但是要添加的关键位:

int bytes = m_pSocket.Receive(tByte);
// now process "bytes" bytes **only** from tByte, nothing that this
// could be part of a message, an entire message, several messages, or
// the end of message "A", the entire of message "B", and the first byte of
// message "C" (which might not be an entire character)

特别是对于文本格式,无法开始解码,直到您确定已缓冲整个消息为止,因为多字节字符可能会在两条消息之间分割。

您的接收循环中也可能存在问题,但您没有显示(没有调用Receive),因此我们无法发表评论。