我正在使用 C++ 学习非常基本的套接字编程,但我陷入了尝试通过套接字发送随机生成的 int 的部分。
服务器.cpp
int code = rand();
send(connfd, (char*)code, sizeof(int), 0);
Run Code Online (Sandbox Code Playgroud)
客户端.cpp
int code = 0;
recv(connfd, (char*)code, sizeof(int), 0);
Run Code Online (Sandbox Code Playgroud)
我究竟做错了什么?
对于初学者:
您没有检查两个调用的返回值。套接字(本质上)是出了名的容易出错。
假设所有字节都将一起发送和接收 - 但 TCP 很容易出现分段、碎片、部分发送以及各种情况,您永远不应该假设您会收到一次调用中发送的所有内容。这使得检查返回值变得更加重要!
您所做的转换:(char*)code是不正确的。更适合这样做(char*)&code,但它不识别部分接收。
假设您使用 TCP 套接字:
发送:
int data = rand();
char* tosend = (char*)&data;
int remaining = sizeof(data);
int result = 0;
int sent = 0;
while (remaining > 0) {
result = send(connfd, tosend+sent, remaining, 0);
if (result > 0) {
remaining -= result;
sent += result;
}
else if (result < 0) {
printf("ERROR!\n");
// probably a good idea to close socket
break;
}
}
Run Code Online (Sandbox Code Playgroud)
收到:
int value = 0;
char* recv_buffer = (char*)&value;
int remaining = sizeof(int);
int received = 0
int result = 0;
while (remaining > 0) {
result = recv(connfd, recv_buffer+received, remaining, 0);
if (result > 0) {
remaining -= result;
received += result;
}
else if (result == 0) {
printf("Remote side closed his end of the connection before all data was received\n");
// probably a good idea to close socket
break;
}
else if (result < 0) {
printf("ERROR!\n");
// probably a good idea to close socket
break;
}
}
Run Code Online (Sandbox Code Playgroud)
对于 UDP 套接字,在错误检查、内存缓冲区的转换等方面,一些原理保持不变。但是对于 UDP,您不应该执行“循环”操作,因为 UDP 是数据报协议。