我想知道是否有人可以解释为什么两个单独的send()调用会在同一个recv()缓冲区中使用环回地址进行测试,但一旦切换到两个远程计算机,他们将需要两个recv()调用?我一直在看wireshark的捕获,但似乎无法理解为什么会发生这种情况。也许有人可以批评我的代码,告诉我哪里出错了。来自服务器的两条传入消息对客户端的长度不确定。顺便说一下,我在Ubuntu中使用了BSD sockets和C。
在下面的例子中,我分析整个缓冲区以从中提取两条独立的消息,我承认这不是一个理想的方法。
-------服务器端--------

// Send greeting string and receive again until end of stream
ssize_t numBytesSent = send(clntSocket, greeting, greetingStringLen, 0);
if (numBytesSent < 0)
  DieWithSystemMessage("send() failed");

//-----------------------------Generate "RANDOM" Message -----------------------

srand(time(NULL)); //seed random number from system clock

size_t randomStringLen = rand() % (RANDOMMSGSIZE-3); //generates random num
                                                     // betweeen 0 and 296

char randomMsg [RANDOMMSGSIZE] = "";

// declare and initialize allowable characteer set for the
const char charSet[] = "abcdefghijklmnopqrstuvwxyzABCDEFGHIJKLMNOPQRSTUVWXYZ";
if (randomStringLen) {
    --randomStringLen;
    for (size_t i = 0; i < randomStringLen; i++) {
        int p = rand() % (int) (sizeof charSet - 1);
        randomMsg[i] = charSet[p];
    }
    randomStringLen = strlen(randomMsg);
    printf("Random String Size Before newline: %d\n", (int)randomStringLen);

strcat(randomMsg,"\r\n");
}

randomStringLen = strlen(randomMsg);

printf("Random String: %s\n", randomMsg);

//-----------------------------Send "RANDOM" Message ---------------------------

// Send greeting string and receive again until end of stream
numBytesSent = send(clntSocket, randomMsg, randomStringLen, 0);
if (numBytesSent < 0)
  DieWithSystemMessage("send() failed");

//------------------------------------------------------------------------------

------客户端-------
//----------------------------- Receive Server Greeting ---------------------------

char buffer[BUFSIZE] = ""; // I/O buffer
// Receive up to the buffer size (minus 1 to leave space for
// a null terminator) bytes from the sender
ssize_t numBytesRcvd = recv(sock, buffer, BUFSIZE - 1, 0);

if (numBytesRcvd < 0)
  DieWithSystemMessage("recv() failed");
buffer[numBytesRcvd] = '\0'; //terminate the string after calling recv()

printf("Buffer contains: %s\n",buffer); // Print the buffer

//printf("numBytesRecv: %d\n",(int)numBytesRcvd); // Print the buffer


//------------------------ Extracts the random message from buffer ---------------------------

char *randomMsg = strstr(buffer, "\r\n"); // searches from first occurance of substring
char randomMessage [BUFSIZE] = "";
strcat(randomMessage, randomMsg+2);

int randomStringLen = strlen(randomMessage)-2;

printf("Random Message: %s\n",randomMessage); // Print the buffer

char byteSize [10];
sprintf(byteSize,"%d", randomStringLen);
printf("ByteSize = %s\n",byteSize);

//----------------------- Send the number for random bytes recieved -------------------------

size_t byteStringLen = strlen(byteSize); // Determine input length

numBytes = send(sock, byteSize, byteStringLen, 0);
if (numBytes < 0)
  DieWithSystemMessage("send() failed");
else if (numBytes != byteStringLen)
  DieWithUserMessage("send()", "sent unexpected number of bytes");

shutdown(sock,SHUT_WR); // further sends are disallowed yet recieves are still possible

//----------------------------------- Recieve Cookie ----------------------------------------

最佳答案

在Unix系统上recvsend只是readwrite的特殊情况,它们接受附加标志。(Windows也用Winsock来模拟这一点)。
您不应该假设一个recv对应于一个send,因为这通常不是真的(就像您可以在多个部分中读取一个文件,即使它是在一次写入中写入的一样)。相反,您应该用一个头来开始每个“消息”,该头告诉您消息的长度,如果知道单独的消息是什么很重要,或者像普通文件一样读取流,如果它不重要。

10-08 06:50
查看更多