简体   繁体   English

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

[英]C# TCP client sending but not receiving messages

I inherited some code for a TCP client. 我为TCP客户端继承了一些代码。 It sends a message, then when complete waits for a confirmation message. 它发送一条消息,然后在完成时等待确认消息。 Currently it sends the message, but when it waits for the reply message it never receives it. 当前,它发送消息,但是在等待回复消息时,它永远不会收到消息。 The SendMessage() method is what is called externally. SendMessage()方法是在外部调用的方法。

I set breakpoints and can see it hits the Receive() method, but never the ReceiveCallback() 我设置了断点,可以看到它击中了Receive()方法,但从未遇到过ReceiveCallback()

Any help or nudge in the right direction is appreciated. 朝正确方向的任何帮助或推动表示赞赏。

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();
        }
    }
}

Your SendMessage and Receive functions don't actually to anything. 您的SendMessageReceive函数实际上没有任何作用。 They just send and receive bytes. 他们只是发送和接收字节。 They have no notion of a "message", do not mark the end of messages when sending them, nor recognize the ends of messages when receiving them. 它们没有“消息”的概念,在发送消息时不标记消息的结尾,在接收消息时也不识别消息的结尾。 Simply put, you forgot to implement a network protocol and are assuming that TCP is a message service when it is actually a byte stream service. 简而言之,您忘记了实现网络协议,并假设TCP实际上是字节流服务,但它假定它是消息服务。

If you need to send and receive messages, you have to precisely define what a "message" is and write code to send and receive them. 如果需要发送和接收消息,则必须精确定义什么是“消息”,并编写代码以发送和接收消息。 It won't work by magic. 魔术不会起作用。

As David Schwartz pointed out, you need a way of delimiting messages. 正如David Schwartz指出的那样,您需要一种分隔消息的方法。

Take a look how WebSocket data is framed . 看一下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 ...                |
+---------------------------------------------------------------+

In the end it was something no one could have known. 最后,这是没人能知道的。 These were HL7 messages, and there was a missing hidden character on the end of the message that was missing. 这些是HL7消息,并且消息末尾缺少一个丢失的隐藏字符。 The receiving party was waiting for the message to finish sending, but without this character it never saw a complete message, thus never sent back the confirmation. 接收方正在等待消息完成发送,但是如果没有此字符,它将永远不会看到完整的消息,因此也就不会发送回确认信息。

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM