C# TCP 客户端发送但不接收消息

本文关键字:消息 TCP 客户端 | 更新日期: 2023-09-27 18:36:45

我继承了一些TCP客户端的代码。 它发送一条消息,然后在完成后等待确认消息。 当前它发送消息,但在等待回复消息时,它永远不会收到它。 SendMessage()方法就是所谓的外部方法。

我设置了断点,可以看到它命中了Receive()方法,但从未命中ReceiveCallback()

任何帮助或推动正确的方向,不胜感激。

public class SocketService
{
    private ManualResetEvent connectDone = new ManualResetEvent(false);
    private ManualResetEvent sendDone = new ManualResetEvent(false);
    private ManualResetEvent receiveDone = new ManualResetEvent(false);
    string ipAddress;
    private int portNum;
    string returnMessage;
    // private string hostName = Dns.GetHostName ();
    public SocketService(string ipAddress, int portNum)
    {
        this.ipAddress = ipAddress;
        this.portNum = portNum;
    }
    public event Logging OnLogging;
    private void WriteLogMessage(string message)
    {
        if (this.OnLogging != null)
            this.OnLogging(message);
    }
    //char endOfLineSeparator = (char) 0x1C;
    //char cr = (char) 0x0D;
    //char vt = (char) 0x0B;
    public string SendMessage(string message)
    {
        IPAddress ip = IPAddress.Parse(this.ipAddress);
        IPEndPoint remoteEP = new IPEndPoint(ip, portNum);
        connectDone.Reset();
        Socket client = new Socket(AddressFamily.InterNetwork,
                                    SocketType.Stream,
                                    ProtocolType.Tcp);
        client.BeginConnect(remoteEP,
                            new AsyncCallback(ConnectCallback),
                            client);
        connectDone.WaitOne();
        //sendDone.Reset();
        WriteLogMessage("send message");
        Send(client, message);
        sendDone.WaitOne();
        //receiveDone.Reset();
        WriteLogMessage("receive message");
        Receive(client);
        receiveDone.WaitOne();
        client.Shutdown(SocketShutdown.Both);
        client.Close();
        return this.returnMessage;
    }
    private void Send(Socket client, String data)
    {
        byte[] byteData = Encoding.ASCII.GetBytes(data);
        client.BeginSend(byteData,
                        0,
                        byteData.Length,
                        0,
                        new AsyncCallback(SendCallback),
                        client);
    }
    private void SendCallback(IAsyncResult ar)
    {
        Socket client = (Socket)ar.AsyncState;
        int bytesSent = client.EndSend(ar);
        sendDone.Set();
    }
    private void ConnectCallback(IAsyncResult ar)
    {
        Socket client = (Socket)ar.AsyncState;
        client.EndConnect(ar);
        connectDone.Set();
    }
    private void Receive(Socket client)
    {
        StateObject state = new StateObject(client);
        client.BeginReceive(state.Buffer,
                            0,
                            StateObject.BufferSize,
                            0,
                            new AsyncCallback(ReceiveCallback),
                            state);
    }
    private void ReceiveCallback(IAsyncResult ar)
    {
        StateObject state = (StateObject)ar.AsyncState;
        Socket client = state.WorkSocket;
        int bytesRead = client.EndReceive(ar);
        if (bytesRead > 0)
        {
            state.StoredContent.Append(Encoding.ASCII.GetString(state.Buffer, 0, bytesRead));
            client.BeginReceive(state.Buffer,
                                0,
                                StateObject.BufferSize,
                                0,
                                new AsyncCallback(ReceiveCallback),
                                state);
            WriteLogMessage(state.StoredContent.ToString());
        }
        else
        {
            this.returnMessage = state.StoredContent.ToString();
            receiveDone.Set();
        }
    }
}

C# TCP 客户端发送但不接收消息

你的SendMessageReceive函数实际上没有任何意义。它们只是发送和接收字节。他们没有"消息"的概念,在发送消息时不会标记消息的结尾,也不会在接收消息时识别消息的结尾。简单地说,你忘记了实现网络协议,并假设TCP是一个消息服务,而它实际上是一个字节流服务。

如果需要发送和接收消息

,则必须精确定义"消息"是什么,并编写代码来发送和接收它们。它不会通过魔法起作用。

正如David Schwartz指出的那样,你需要一种分隔消息的方法。

看看 WebSocket 数据是如何构建的。

0                   1                   2                   3
 0 1 2 3 4 5 6 7 8 9 0 1 2 3 4 5 6 7 8 9 0 1 2 3 4 5 6 7 8 9 0 1
+-+-+-+-+-------+-+-------------+-------------------------------+
|F|R|R|R| opcode|M| Payload len |    Extended payload length    |
|I|S|S|S|  (4)  |A|     (7)     |             (16/64)           |
|N|V|V|V|       |S|             |   (if payload len==126/127)   |
| |1|2|3|       |K|             |                               |
+-+-+-+-+-------+-+-------------+ - - - - - - - - - - - - - - - +
|     Extended payload length continued, if payload len == 127  |
+ - - - - - - - - - - - - - - - +-------------------------------+
|                               |Masking-key, if MASK set to 1  |
+-------------------------------+-------------------------------+
| Masking-key (continued)       |          Payload Data         |
+-------------------------------- - - - - - - - - - - - - - - - +
:                     Payload Data continued ...                :
+ - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - +
|                     Payload Data continued ...                |
+---------------------------------------------------------------+

最后,这是没有人能知道的事情。 这些是 HL7 消息,消息末尾缺少一个缺少的隐藏字符。 接收方正在等待消息完成发送,但是没有这个字符,它永远不会看到完整的消息,因此永远不会发回确认。