首先,您的 2 个函数比它们需要的要复杂一些。它们可以被简化。
例如,可以删除 send_data() 中的整个 SIZE 和 LIMIT 处理,因为您直接发送 data 缓冲区,所以只需给 send() 与 data 中一样多的字节数和让send() 告诉你它实际接受了多少字节。
但更重要的是,receive_data() 需要考虑输入 buffer 的大小。您只是盲目地阅读,对实际发送的数据量没有任何概念。您正在将一个可变长度的字符串传递给send_data(),这很容易超过receive_data() 的调用者所期望的buffer 大小。
另外,你根本没有任何错误处理。
尝试类似的方法:
int send_data(int sockfd, const void *buffer, size_t bufsize)
{
const char *pbuffer = (const char*) buffer;
while (bufsize > 0)
{
int n = send(sockfd, pbuffer, bufsize, 0);
if (n < 0) return -1;
pbuffer += n;
bufsize -= n;
}
return 0;
}
int receive_data(int sockfd, void *buffer, size_t bufsize)
{
char *pbuffer = (char*) buffer;
while (bufsize > 0)
{
int n = recv(sockfd, pbuffer, bufsize, 0);
if (n <= 0) return n;
pbuffer += n;
bufsize -= n;
}
return 1;
}
然后您可以在这些功能之上构建其他功能。例如,在发送字符之前将字符串的长度作为整数发送,例如:
int send_int32(int sockfd, int32_t data)
{
data = htonl(data);
return send_data(sockfd, &data, sizeof(data));
}
int receive_int32(int sockfd, int32_t *data)
{
int ret = receive_data(sockfd, data, sizeof(*data));
if (ret <= 0) *data = 0;
else *data = ntohl(*data);
return ret;
}
int send_str(int sockfd, const char *data)
{
int32_t size = strlen(data);
int ret = send_int32(sockfd, size);
if (ret == 0) ret = send_data(sockfd, data, size);
return ret;
}
int receive_str(int sockfd, char **data)
{
*data = NULL;
int32_t size;
int ret = receive_int32(sockfd, &size);
if (ret > 0) {
*data = malloc(size+1);
if (*data == NULL) return -1;
ret = receive_data(sockfd, *data, size);
if (ret <= 0) {
free(*data);
*data = NULL;
}
else {
(*data)[size] = '\0';
}
}
return ret;
}
send_str(sockfd, "Hello World!");
char *str;
if (receive_str(sockfd, &str) > 0) {
...
free(str);
}