Warning: file_get_contents(/data/phpspider/zhask/data//catemap/3/sockets/2.json): failed to open stream: No such file or directory in /data/phpspider/zhask/libs/function.php on line 167

Warning: Invalid argument supplied for foreach() in /data/phpspider/zhask/libs/tag.function.php on line 1116

Notice: Undefined index: in /data/phpspider/zhask/libs/function.php on line 180

Warning: array_chunk() expects parameter 1 to be array, null given in /data/phpspider/zhask/libs/function.php on line 181

Warning: file_get_contents(/data/phpspider/zhask/data//catemap/8/redis/2.json): failed to open stream: No such file or directory in /data/phpspider/zhask/libs/function.php on line 167

Warning: Invalid argument supplied for foreach() in /data/phpspider/zhask/libs/tag.function.php on line 1116

Notice: Undefined index: in /data/phpspider/zhask/libs/function.php on line 180

Warning: array_chunk() expects parameter 1 to be array, null given in /data/phpspider/zhask/libs/function.php on line 181
Sockets TCP套接字仅接收消息的一部分_Sockets_Tcp - Fatal编程技术网

Sockets TCP套接字仅接收消息的一部分

Sockets TCP套接字仅接收消息的一部分,sockets,tcp,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.

我使用以下代码执行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=新字节[3000]; 有没有办法不硬编码这个数字3000。它大部分时间都在工作,但对于较长的字符串,它只能得到一半的时间。 我希望它能够处理可变大小的消息,而不是将字节大小设置为30000 谢谢阅读。它告诉您如何确定服务器响应的结束,以便您知道要读取多少字节。您必须首先读取并处理服务器的响应头,以便了解剩余数据(如果有的话)是如何传输的。然后,您可以相应地继续从套接字读取,潜在地解析您所读取的内容,直到实际到达响应的末尾。您当前的阅读代码甚至无法满足该要求

例如(伪代码):

line=读取CRLF分隔行;
responseNum=从行中提取;
httpVer=从生产线提取;
做
{
行=读取CRLF分隔行;
如果(行==“”)中断;
将行添加到标题列表中;
}
虽然(正确);
如果((响应数/100)!=1)&&
(responseNum!=204)&&
(响应数!=304)&&
(请求不是“头”))
{
if((标题具有“传输编码”)&&
(标题[“传输编码”]!=“标识”))
{
做
{
行=读取CRLF分隔行;
chunkLen=从行中提取,解码十六进制值;
如果(chunkLen==0)中断;
准确读取chunkLen字节数;
读取并丢弃CRLF分隔行;
}
虽然(正确);
做
{
行=读取CRLF分隔行;
如果(行==“”)中断;
将行添加到标题列表,如果存在,则覆盖;
}
虽然(正确);
如果不仅仅是“分块”,则基于头[“传输编码”]值解码/转换读取数据
}
else if(标题具有“内容长度”)
{
准确读取标题[“内容长度”]字节数
}
else if(标题[“内容类型”]==多部分/byteranges)
{
边界=标题[“内容类型”][“边界”];
读取并解析MIME编码数据,直到到达“-”+边界+“--”行;
}
其他的
{
阅读直到断开;
}
}
如果(((httpVer>=1.1)和&(头[“连接”]=“关闭))||
((httpVer<1.1)和&(标题[“连接”!=“保持活动”))
{
断开
}
我把它留作一个练习,让您在代码中实际实现它。

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

例如(伪代码):

line=读取CRLF分隔行;
responseNum=从行中提取;
httpVer=从生产线提取;
做
{
行=读取CRLF分隔行;
如果(行==“”)中断;
将行添加到标题列表中;
}
虽然(正确);
如果((响应数/100)!=1)&&
(responseNum!=204)&&
(响应数!=304)&&
(请求不是“头”))
{
if((标题具有“传输编码”)&&
(标题[“传输编码”]!=“标识”))
{
做
{
行=读取CRLF分隔行;
chunkLen=从行中提取,解码十六进制值;
如果(chunkLen==0)中断;
准确读取chunkLen字节数;
读取并丢弃CRLF分隔行;
}
虽然(正确);
做
{
行=读取CRLF分隔行;
如果(行==“”)中断;
将行添加到标题列表,如果存在,则覆盖;
}
虽然(正确);
如果不仅仅是“分块”,则基于头[“传输编码”]值解码/转换读取数据
}
else if(标题具有“内容长度”)
{
准确读取标题[“内容长度”]字节数
}
else if(标题[“内容类型”]==多部分/byteranges)
{
边界=标题[“内容类型”][“边界”];
读取并解析MIME编码数据,直到到达“-”+边界+“--”行;
}
其他的
{
阅读直到断开;
}
}
如果(((httpVer>=1.1)和&(头[“连接”]=“关闭))||
((httpVer<1.1)和&(标题[“连接”!=“保持活动”))
{
断开
}

我把它留作练习,让您在代码中实际实现它。

读取套接字的代码在哪里?您必须一直读取,直到服务器关闭连接,或者您已收到最后一个数据块,或者读取内容长度标题指示的字节,或者。。。使用诸如WebClient或HttpClient之类的HTTP库。我无权访问服务器代码。我确信他们收到了全部的信息。因为直到他们收到一个完整的字符串并通过验证,他们才用另一个字符串响应。问题不在于阅读。接收响应时会出现问题,如@CodeCaster所说-从套接字读入bytesReceived数组的代码在哪里?@MartinJames:oops抱歉。。我不小心拆下了那条线。为什么不使用URL和URLConnection?他们解决了所有这些问题,还有很多其他问题。读取套接字的代码在哪里?您必须一直读取,直到服务器关闭连接,或者您已收到最后一个数据块,或者读取内容长度标题指示的字节,或者。。。使用HTTP库,如WebClient或HttpClient。我没有访问HTTP库的权限
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;
}