C ++下的套接字问题

时间:2009-07-31 10:42:59

标签: c++ sockets

我以下列方式打开了服务器连接

SOCKADDR_IN SockAddr;
SockAddr.sin_port=htons(445);
SockAddr.sin_family=AF_INET;
SockAddr.sin_addr.s_addr=*((unsigned long*)host->h_addr);

// Attempt to connect to server
if(connect(Socket,(SOCKADDR*)(&SockAddr),sizeof(SockAddr))!=0)
{
    printf("Failed to establish connection with server\r\n");
    WSACleanup();
    system("PAUSE");
    return 0;
}

然后我尝试通过TCP连接发送数据,如下所示:

unsigned char completePacket[100] = something;

send(Socket, (char *) completePacket, 100, 0);

这样可以正常工作2次,但第三次似乎没有发送数据包... 我是否需要在每次发送后冲洗插座或以某种方式重置它们?

由于

4 个答案:

答案 0 :(得分:3)

send(Socket, (char *) completePacket, 100, 0);

很好,但你应该总是检查返回值。 send可能实际发送的数量少于你告诉它的数量(当你发送300字节时,这不太可能是问题。)

您无需刷新插座。

问题可能在接收方?请记住,TCP提供流,而不是数据包或消息。一个发送呼叫可能需要多次recv调用才能全部接收它们。多个发送呼叫发送的数据可能只在一次recv呼叫中接收。您必须跟踪您收到的数据量。

如果要查看通过网络传输的数据,请安装Wireshark等网络监视器。

答案 1 :(得分:3)

当您经常发送少量数据时,TCP / IP堆栈会根据其流量控制算法缓冲数据。这是为了获得最佳带宽利用率。这被称为Nagle的算法。您的观察结果很可能是由于Nagle的算法开启(默认情况下打开)。但它可能完全不同于其他东西。您可以通过以下方式确定消除过程。

将以下代码放在connect

之后
int flag = 1;
int result = setsockopt(sock,            
                 IPPROTO_TCP,
                 TCP_NODELAY,
                 (char *) &flag,
                 sizeof(flag));
if (result < 0)
... handle the error ...

如果您发现结果没有任何差异,则问题不在于默认的流量控制机制。

答案 2 :(得分:2)

如果另一方在发送下一个数据包之前没有确认该数据包,那么由于Nagle's algorithm中指定的RFC 896,其他数据包可能会延迟。实质上,只要已经发送的未完成数据得到确认,就会缓冲更多的小发送并在一个更大的数据包中发送。这有助于防止网络被大量小数据包淹没。

答案 3 :(得分:1)

与所有套接字API一样,您应该检查send()的返回值(应该是发送的字节数),然后使用诊断函数来查看任何问题。