我想知道是否有人可以阐明为什么两个单独的 send() 调用最终会在同一个 recv() 缓冲区中使用环回地址进行测试,但一旦切换到两台远程机器,他们将需要两个 recv( ) 调用?我一直在查看 wireshark 捕获,但似乎无法理解为什么会发生这种情况。也许有人可以批评我的代码并告诉我哪里出了问题。来自服务器的两个传入消息对于客户端来说是不确定的长度。顺便说一下,我在 Ubuntu 中使用 C 来使用 BSD 套接字。
在下面显示的示例中,我将解析整个缓冲区以从中提取两条单独的消息,我承认这不是理想的方法。
--------服务器端--------
// 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 系统上,recv
和 send
只是 read
和 write
的特例,它们接受额外的标志. (Windows 也使用 Winsock 模拟这一点)。
你不应该假设一个 recv
对应一个 send
因为这通常是不正确的(就像你可以读取多个部分的文件一样,即使它是一次写成的)。相反,您应该在每条“消息”的开头加上一个 header , header 告诉您消息的长度,如果知道单独的消息是什么很重要,或者如果它不重要,则像普通文件一样读取流。
关于c - (C 套接字编程)来自服务器的单独 send() 调用在同一个客户端 recv() 缓冲区中结束,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/27096243/