如何使用 TCP sockets 发送和接收一长串 integers?
在短数组的情况下,可以使用函数recv(.., 4*size of array)
接收一次,但是当数组的大小太长时,我无法正确接收数据。
int main(void)
{
int listenfd = 0, connfd = 0;
int i,j,x;
int fd;
unsigned int *pic;
struct sockaddr_in serv_addr;
char *recvBuff;
clock_t t;
//Allocate memory for a 24-bit 640x480 rgb image
pic = (int*)malloc(10*sizeof(int));
recvBuff = (char*)malloc(1*sizeof(char));
for(i = 0; i < 10 ; i++){
pic[i] = 20;
}
//Create the TCP socket
listenfd = socket(AF_INET, SOCK_STREAM, 0);
memset(&serv_addr, '0', sizeof(serv_addr));
memset(pic, '0', sizeof(pic));
serv_addr.sin_family = AF_INET;
serv_addr.sin_addr.s_addr = htonl(INADDR_ANY);
serv_addr.sin_port = htons(7); // la valeur du port
bind(listenfd, (struct sockaddr*)&serv_addr, sizeof(serv_addr));
listen(listenfd, 10);
//fprintf(stdout,"End Creating Socket4\n");
connfd = accept(listenfd, (struct sockaddr*)NULL, NULL);
while(1)
{
recv(connfd,recvBuff, sizeof(char),MSG_WAITALL);
//printf("BUFF: %s\n",recvBuff);
//Wait for client request
if(strcmp(recvBuff,"A")){
printf("Error in input\n");
}else
write(connfd, pic, 921600);
}
close(connfd);
}
回答1
在短数组的情况下,可以使用函数
recv(.., 4*size of array)
一次接收
这是不能保证的。任何对 recv()
的调用都可以返回比请求更少的字节,甚至只有 1 个字节。因此,您总是需要在循环中调用 recv()
,直到您实际收到与您期望的一样多的字节,例如:
ssize_t recv_all(int skt, void *buf, size_t bufsize)
{
char *ptr = (char*) buf;
while (bufsize > 0)
{
ssize_t recvd = recv(skt, ptr, bufsize, 0);
if (recvd <= 0) return recvd;
ptr += recvd;
bufsize -= recvd;
}
return 1;
}
然后你可以这样称呼它:
int32_t *arr = (int32_t*) malloc(sizeof(int32_t) * count);
...
if (recv_all(..., arr, sizeof(int32_t) * count) <= 0)
{
// error, or peer disconnected...
}
else
{
// use arr as needed...
}
您也应该为 send()
做同样的事情,例如:
ssize_t send_all(int skt, const void *buf, size_t bufsize)
{
const char *ptr = (const char*) buf;
while (bufsize > 0)
{
ssize_t sent = send(skt, ptr, bufsize, 0);
if (sent < 0) return sent;
ptr += sent;
bufsize -= sent;
}
return 0;
}
int32_t *arr = (int32_t*) malloc(sizeof(int32_t) * count);
...
if (send_all(..., arr, sizeof(int32_t) * count) < 0)
{
// error...
}
else
{
// arr sent in full...
}
回答2
首先,值得注意的是 recv()
根本不关心它接收到的数据类型,只关心它的大小。
所以你所需要的只是一个在循环中调用 recv()
直到它接收到所有请求的数据的函数
// Returns the number of bytes read, or -1 in the case of an error
ssize_t recv_all(const int sock, void * const buf, const size_t n)
{
ssize_t len = 0;
ssize_t total_read = 0;
while (n > (size_t)total_read)
{
len = recv(sock, (char *)buf + total_read, n - total_read, MSG_WAITALL);
switch (len)
{
case -1:
return -1;
case 0:
break;
default:
total_read += len;
}
}
return total_read;
}