Artyomska Artyomska - 1 month ago 15
C Question

UDP client doesn't receive anything from server in C

So I am trying to make a basic server and client using UDP and C,in Linux. The server must receive from the client two char arrays(buffer and aux), and the client must receive from the server an int array which will contain the positions where the character given in aux is in the buffer array (for example, if we have aaabaa, and a in aux, the client must print 01245). The problem is that the client always print 00000 etc, depending on the length of the frecv array.

Here is my code:

//Client

#include <sys/types.h>
#include <sys/socket.h>
#include <netinet/in.h>
#include <netinet/ip.h>
#include <unistd.h>
#include <stdlib.h>
#include <stdio.h>
#include <string.h>
#include <arpa/inet.h>
#include <netdb.h>
#include <stdint.h>

int main(int argc, char *argv[])
{

int clientSocket, portNum, nBytes1,portno,nBytes2,nBytes3,i;
int32_t frecv[1024],frecv2[1024];
char buffer[1024],aux[2];
struct sockaddr_in serverAddr;
socklen_t addr_size;
struct hostent *server1;

clientSocket = socket(PF_INET, SOCK_DGRAM, 0);
portno=atoi(argv[2]);
server1 = gethostbyname(argv[1]);
serverAddr.sin_family = AF_INET;
serverAddr.sin_port = htons(portno);
bcopy((char *)server1->h_addr, (char *)&serverAddr.sin_addr.s_addr,server1->h_length);;
memset(serverAddr.sin_zero, '\0', sizeof serverAddr.sin_zero);

addr_size = sizeof serverAddr;

while(1)
{
printf("Introdu un sir de caractere:\n");
fgets(buffer,1024,stdin);
printf("You typed: %s\n",buffer);

printf("Introdu un caracter:\n");
fgets(aux,2,stdin);
printf("You typed: %s\n",buffer);
printf("You typed: %s\n",aux);

nBytes1 = strlen(buffer) + 1;
nBytes2 = strlen(aux) + 1;
sendto(clientSocket,buffer,nBytes1,0,(struct sockaddr *)&serverAddr,addr_size);
sendto(clientSocket,aux,nBytes2,0,(struct sockaddr *)&serverAddr,addr_size);

nBytes3 = recvfrom(clientSocket,frecv2,1024,0,(struct sockaddr *)&serverAddr,&addr_size);
for (i = 0 ; i < nBytes3 ; i++)
frecv[i] = ntohl(frecv2[i]);
for (i=0;i<nBytes3;i++)
printf("%d",frecv[i]);
printf("\n");
return 0;
}


}


//Server

#include <sys/types.h>
#include <sys/socket.h>
#include <netinet/in.h>
#include <netinet/ip.h>
#include <unistd.h>
#include <stdlib.h>
#include <stdio.h>
#include <string.h>
#include <arpa/inet.h>
#include <netdb.h>
#include <stdint.h>

int main(int argc, char *argv[])
{
int udpSocket,portno,l;
char buffer[1024];
char aux[2];
struct sockaddr_in serverAddr,client;
socklen_t addr_size;
int i;

udpSocket = socket(AF_INET, SOCK_DGRAM, 0);
if (udpSocket < 0)
{
printf("Eroare la crearea socketului server\n");
return 1;
}
memset(&serverAddr, 0, sizeof(serverAddr));
portno=atoi(argv[1]);
serverAddr.sin_port = htons(portno);
serverAddr.sin_family = AF_INET;
serverAddr.sin_addr.s_addr = INADDR_ANY;


if (bind(udpSocket, (struct sockaddr *) &serverAddr, sizeof(serverAddr)) < 0)
{
perror ("Eroare la bind");
exit (1);
}
else
printf ("Bind successful\n");

l = sizeof(client);
memset(&client, 0, sizeof(client));

while(1)
{
int nBytes1,nBytes2,j;
int32_t frecv[1024],frecv2[1024];
nBytes1 = recvfrom(udpSocket,buffer,1024,0,(struct sockaddr *)&client, &l);
nBytes2 = recvfrom(udpSocket,aux,2,0,(struct sockaddr *)&client, &l);

printf("You typed: %s\n",buffer);
printf("You typed: %s\n",aux);
printf("You typed: %d\n",nBytes1);
printf("You typed: %d\n",nBytes2);

for(i=0;i<nBytes1-1;i++)
if (buffer[i]==aux[0])
{
frecv[j]=i;
j++;
}
for(i=0;i<j;i++)
printf("%d",frecv[i]);
for (i = 0 ; i < j ; i++)
frecv2[i] = htonl(frecv[i]);
printf("\n");
sendto(udpSocket,frecv2,j,0,(struct sockaddr *)&client,l);
printf("Done\n");
}

return 0;
}

Answer

You're off regarding the amount of data to send/receive when the server responds.

In the server:

sendto(udpSocket,frecv2,j,0,(struct sockaddr *)&client,l);

You don't want to send j bytes. You want to send j elements of type int32_t. So you need to multiply by the element size.

sendto(udpSocket,frecv2,j*sizeof(frecv2[0]),0,(struct sockaddr *)&client,l);

Similarly in the client:

for (i = 0 ; i < nBytes3 ; i++) 
    frecv[i] = ntohl(frecv2[i]);
for (i=0;i<nBytes3;i++)
    printf("%d",frecv[i]);

You read nBytes3, but each element is the size of a int32_t, not just 1 byte. So divide by the element size:

for (i = 0 ; i < nBytes3 / sizeof(frecv2[0]) ; i++) 
    frecv[i] = ntohl(frecv2[i]);
for (i=0;i<nBytes3 / sizeof(frecv2[0]);i++)
    printf("%d",frecv[i]);

One more thing in the server. You fail to initialize j. Set it to 0 at the top of the loop.