TCP Socket仅接收部分消息

时间:2014-01-23 18:05:31

标签: sockets tcp

我使用以下代码执行tcp套接字连接并将字符串发送到IP。但有时在回复中,我没有收到整个文件

     Socket m_socClient;
        IPSelected ="1.1.2.3"
                Port = "80"
                string query ="My Query"
                m_socClient = new Socket(AddressFamily.InterNetwork, SocketType.Stream, ProtocolType.Tcp);
                System.Net.IPAddress remoteIPAddress = System.Net.IPAddress.Parse(IPSelected);
                System.Net.IPEndPoint remoteEndPoint = new System.Net.IPEndPoint(remoteIPAddress, Port);
                m_socClient.Connect(remoteEndPoint);
                try
                {
                    if (m_socClient.Connected)
                    {                       
                        var reQuestToSend = "";


                            reQuestToSend = string.Format("POST /TMHP/Request HTTP/1.1\r\nHost:{0}\r\nContent-Length:{1}\r\n\r\n{2}", "edi-webtest.tmhp.com", Query270.Length, Query270);
                        byte[] bytesToSend = Encoding.ASCII.GetBytes(reQuestToSend);
                        byteCount = m_socClient.Send(bytesToSend, SocketFlags.None);
                        byte[] bytesReceived = new byte[3000];
  byteCount = m_socClient.Receive(bytesReceived, SocketFlags.None);
                        Response271 = Encoding.ASCII.GetString(bytesReceived);

                    }
                }
                catch (Exception ex)
                {
                    EVCommon.Log(ex.Message);

                }
                finally
                {
                    m_socClient.Disconnect(false);
                    m_socClient.Close(5000);
                }

我认为问题在于byte [] bytesReceived = new byte [3000]; 有没有办法不对这个数字3000进行硬编码。它大部分时间都有效,但对于较长的字符串,它只能获得一半。 我希望它处理可变大小的消息,而不是将字节大小设置为30000 谢谢

1 个答案:

答案 0 :(得分:4)

阅读RFC 2616 Section 4.4。它告诉您如何确定服务器响应的结束,以便知道要读取多少字节。您必须首先读取并处理服务器的响应头,以便了解剩余数据(如果有)的传输方式。然后,您可以相应地继续读取套接字,可能会解析您所读取的内容,直到实际到达响应结束。您当前的阅读代码甚至不能满足该要求。

例如(伪代码):

line = read a CRLF-delimited line;

responseNum = extract from line;
httpVer = extract from line;

do
{
    line = read a CRLF-delimited line;
    if (line == "") break;
    add line to headers list;
}
while (true);

if (((responseNum / 100) != 1) &&
    (responseNum != 204) &&
    (responseNum != 304) &&
    (request was not "HEAD"))
{
    if ((headers has "Transfer-Encoding") &&
        (headers["Transfer-Encoding"] != "identity"))
    {
        do
        {
            line = read a CRLF-delimited line;
            chunkLen = extract from line, decode hex value;
            if (chunkLen == 0) break;
            read exactly chunkLen number of bytes;
            read and discard a CRLF-delimited line;
        }
        while (true);

        do
        {
            line = read a CRLF-delimited line;
            if (line == "") break;
            add line to headers list, overwrite if exists;
        }
        while (true);

        decode/transform read data based on headers["Transfer-Encoding"] values if more than just "chunked"
    }
    else if (headers has "Content-Length")
    {
        read exactly headers["Content-Length"] number of bytes
    }
    else if (headers["Content-Type"] == multipart/byteranges)
    {
        boundary = headers["Content-Type"]["boundary"];
        read and parse MIME encoded data until "--"+boundary+"--" line is reached;
    }
    else
    {
        read until disconnected;
    }
}

if (((httpVer >= 1.1) && (headers["Connection"] == "close)) ||
    ((httpVer < 1.1) && (headers["Connection"] != "keep-alive")))
{
    disconnect;
}

我把它作为练习让你在代码中实际实现它。