'How to receive long array of integers with TCP socket in C?
How can I send and receive a long array of integers using TCP sockets?
In the case of short array, the reception is possible using the function recv(.., 4*size of array) one time, however when the size of array is too long, I can't receive data correctly.
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);
}
Solution 1:[1]
In the case of short array, the reception is possible using the function
recv(.., 4*size of array)one time
That is not guaranteed. Any call to recv() can return fewer bytes than requested, even as few as just 1 byte. So you always need to call recv() in a loop until you have actually received as many bytes as are you expecting, eg:
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;
}
And then you can call it like this:
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...
}
You should do the same thing for send() too, eg:
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...
}
Solution 2:[2]
First of all, it's worth noting that recv() doesn't care at all about the type of data it receives, only about its size.
So all you need is a function that calls recv() in a loop until it receives all of the requested data
// 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;
}
Sources
This article follows the attribution requirements of Stack Overflow and is licensed under CC BY-SA 3.0.
Source: Stack Overflow
| Solution | Source |
|---|---|
| Solution 1 | Remy Lebeau |
| Solution 2 | malkaroee |
