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
C# C“套接字TCP发送,消息获取”;";_C#_Sockets_Tcp - Fatal编程技术网

C# C“套接字TCP发送,消息获取”;";

C# C“套接字TCP发送,消息获取”;";,c#,sockets,tcp,C#,Sockets,Tcp,这有点奇怪,如果我解释得不好,我道歉 我使用下面的简单代码发送我从队列中弹出的消息,使用一个简单的TCP套接字,消息通过本地主机发送到同一台机器上的另一个端口- try { Socket.Select(null, writeList, null, 120000000/*120 seconds*/); } catch (SocketException e) { log.Error("Select returned an error waiting to send... " + e.

这有点奇怪,如果我解释得不好,我道歉

我使用下面的简单代码发送我从队列中弹出的消息,使用一个简单的TCP套接字,消息通过本地主机发送到同一台机器上的另一个端口-

try
{
    Socket.Select(null, writeList, null, 120000000/*120 seconds*/);
}
catch (SocketException e)
{
    log.Error("Select returned an error waiting to send... " + e.Message + " Errorcode: " + e.ErrorCode);
    connected = false;
    socket.Close();
}

bool readyToWrite = false;
for (int i = 0; i < writeList.Count; i++)
{
    readyToWrite = true;
}

if (readyToWrite)
{
    try
    {
        //log.Debug("Sending message type: " + message.header.msgType);
        socket.Send(message, message.header.dataLength, SocketFlags.None);                        
        //log.Debug("Message sent");
    }
    catch (SocketException e)
    {
        log.Error(e.Message + " Error code: " + e.ErrorCode);
        connected = false;
        socket.Close();                        
    }

}
else
{
    log.Error("Not able to write - stopping sender thread and closing socket");
    connected = false;
    socket.Close();
}
以及读取方法-

int CReadWriteSocket::Read(void *pData, int nLen) 
{
    char* pcData = (char* )pData;
    int n = nLen;
    // if data size is bigger then network buffer
    // handle it nice
    do
    {
        int r1 = ::recv (m_hSocket, pcData, n, 0);
        if (r1 == SOCKET_ERROR)
        {
            int e = WSAGetLastError();
            if (e == WSAEWOULDBLOCK)
            {
                return nLen - n;
            }
            else
            {
                TRACE("Socket Read error %d\n", e);
                return -1;      // error other than would block detected
            }
        }
        else if (r1 == 0)       // Connection has closed
        {
            TRACE("Socket appears to have closed (zero bytes read)\n");
            return -1;          // Show this as an "error"
        }
        else if (r1 < 0)
        {
            ASSERT(0);
            return nLen - n;
        }

        pcData += r1;
        n -= r1;
    } while (n > 0);

    ASSERT(n == 0);
    return nLen;
}
int-CReadWriteSocket::Read(void*pData,int-nLen)
{
char*pcData=(char*)pData;
int n=nLen;
//如果数据大小大于网络缓冲区
//好好处理
做
{
int r1=:recv(m_hSocket,pcData,n,0);
if(r1==套接字错误)
{
int e=WSAGetLastError();
如果(e==WSAEWOULDBLOCK)
{
返回nLen-n;
}
其他的
{
跟踪(“套接字读取错误%d\n”,e);
return-1;//检测到块以外的错误
}
}
如果(r1==0)//连接已关闭,则为else
{
跟踪(“套接字似乎已关闭(读取零字节)\n”);
return-1;//将其显示为“错误”
}
否则如果(r1<0)
{
断言(0);
返回nLen-n;
}
pcData+=r1;
n-=r1;
}而(n>0);
断言(n==0);
返回nLen;
}
我完全糊涂了,因为这似乎是我到处使用的标准代码,我从来没有见过这样的问题发生

有人建议尝试使用NoDelay套接字选项,但没有任何效果——事实上,根据我所知,这永远不会导致如此长的延迟


如有任何建议,将不胜感激!谢谢。

TCP是一种流协议。您不能假设您发送()的“数据包”将被传递和接收。在传输端,Nagle算法尝试组合在单独的Send()调用中写入的数据,以优化数据的传递。在接收端,您将读取()存储在TCP缓冲区中的内容。如果有任何延迟,If将是传输数据包的组合。发射机和接收机之间的路由器使这一点更加复杂,允许它们将一个IP数据包分割成多个小数据包,以适应传输信道的最大数据包大小(MTU)


换句话说,没有可靠的方法来确保数据包按发送方式发送。一个简单的解决方法是首先传输数据包的大小。在接收端,您首先读取该大小,然后知道如何计算接收到的字节数以重建数据包。

这很奇怪。请考虑使用这些信息来追踪消息,看看它们将走向何方。除非我遗漏了一些明显的信息,否则我很难理解为什么这些信息认为它们已经收到,但实际上没有收到。客户会等吗


尝试int.MaxValue而不是120000000

我不确定这是否是您的问题,我正在利用去年的模糊记忆,因此请原谅这种模糊

我似乎记得,
Socket.Select()
会返回,指示如果流有错误,它没有要读取的数据。您可能希望尝试将流列表的副本传递给error list参数,并查看是否有任何错误

无论
writelist
中有什么内容,您的代码似乎正在发送到同一个套接字。即使您只有一个套接字,我也会将其修改为在
writelist
上操作。否则,您将尝试发送到套接字,即使它不一定表示它已准备好接收数据(即,
socket.Select()
由于某些其他原因返回,例如我上面的预感)。这可能会导致写入操作阻塞,并且可能是使用多个套接字操作时出现延迟的原因

最后,您可以在设置标志后立即跳出
readyToWrite
循环。更好的是,您可以将其重新编码为:

bool readyToWrite = writelist.Any();
但我仍然建议您将其替换为
writelist
上的
foreach
循环:

foreach (Socket sock in writelist)
{
    // do stuff
}

您的客户机代码是什么样子的


通常,我会说,由于您正在运行,您只在本地发送消息,因此您看到的行为几乎肯定是由Nagle的算法引起的,但设置NoDelay属性会禁用这一点。

我的错误,似乎是由于最后的阻塞读取问题。

TCP承诺将按顺序交付;建议至少有一个错误。只是一个快速的观察!订购可能不正确,可能只是看起来不正确,但主要问题是延迟!谢谢,但问题并不是真正的顺序,当他们通过时,这是正确的,这是巨大的30秒延迟的问题。你将不得不更好地记录网络特性。在你的帖子中没有任何东西不表明这是一个简单的硬件问题。但是如果这是一个硬件问题,那么从我的应用程序获得的初始消息如何?似乎只有当我尝试快速连续发送多条消息时,问题才会出现。这也是在一台机器上运行的,通过本地主机连接,因此不太可能与硬件相关。请务必在问题中指出这一点,这并不明显。消息实际上是在本地主机上发送的,因为它是在同一台机器上接收它们的另一个可执行文件。所以不能使用Wireshark。然而,我使用了一个localhost跟踪工具,正如我所说,我发现另一端正在接收该级别的消息,但是select返回并说没有什么可读的…而且,客户机代码是许多其他应用程序正在使用的成熟代码。所以我很有信心这一方是好的。而select最终发现了一些东西需要阅读,这只是del
bool readyToWrite = writelist.Any();
foreach (Socket sock in writelist)
{
    // do stuff
}