0
votes

I have a UDP client and a UDP server. The flow of the program is: first the server is executed from the terminal, the terminal creates a socket and binds it and waits for a filename from the client. In another terminal the client is executed. Here also a socket is created, and a connection is established with the server. Then a filename is provided to the client. This filename is sent to the server using sendto() function. The server is able to receive filename from the client and the server is also sending the data in the file to the client. However the receiver on the other side keeps waiting for the data from the server.

The code for the UDP client and server is as shown below.

UDP Server:

#include<sys/types.h>
#include<sys/socket.h>
#include<netinet/in.h>
#include<sys/stat.h>
#include<unistd.h>
#include<stdlib.h>
#include<stdio.h>
#include<fcntl.h>
int main()
{
    int cont,create_socket,new_socket,addrlen,fd;
    int bufsize = 1024;
    int nameLen=0;
    int client_address_size=0;
    char *buffer = malloc(10);
    char fname[256];
    struct sockaddr_in address,client;

    if ((create_socket = socket(AF_INET,SOCK_DGRAM,0)) > 0)
    printf("The socket was created\n");

    address.sin_family = AF_INET;
    address.sin_addr.s_addr = INADDR_ANY;
    address.sin_port = htons(15000);

    if (bind(create_socket,(struct sockaddr *)&address,sizeof(address))== 0)
        printf("Binding Socket\n");

    nameLen=sizeof(address);

    if (getsockname(create_socket,(struct sockaddr *)&address,&nameLen)<0)
    {
        printf("\n\ngetsockname() error\n");
        exit(3);
    }

    printf("Port assigned is %d\n", ntohs(address.sin_port));

    client_address_size=sizeof(client);

    if(recvfrom(create_socket,fname, 255,0,(struct sockaddr *) &client,&client_address_size)<0)
    {
        printf("\n\nrecvfrom() failed\n");
        exit(4);
    }

    printf("A request for filename %s Received..\n", fname);

    if ((fd=open(fname, O_RDONLY))<0)
    {
        perror("File Open Failed");
        exit(0);
    }

    while((cont=read(fd, buffer, 10))>0) 
    {
        //sleep(1);
        sendto(create_socket,buffer,cont,0,(struct sockaddr *) &client,&client_address_size);
        printf("\n\nPacket sent\n");
    }

    printf("Request Completed\n");

    return close(create_socket);
}

UDP Client:

#include<sys/socket.h>
#include<sys/types.h>
#include<netinet/in.h>
#include<unistd.h>
#include<stdlib.h>
#include<stdio.h>

int main()
{
    int create_socket,cont;
    char *arg="127.0.0.1";
    int bufsize = 1024;
    int server_address_size=0;
    char *buffer = malloc(10);
    char fname[256];
    struct sockaddr_in address,server;

    if ((create_socket = socket(AF_INET,SOCK_DGRAM,0)) > 0)
        printf("The Socket was created\n");

    address.sin_family = AF_INET;
    address.sin_port = htons(15000);
    address.sin_addr.s_addr=inet_addr(arg);

    if (connect(create_socket,(struct sockaddr *) &address,sizeof(address)) == 0)
        printf("The connection was accepted with the server %s...\n",arg);

    printf("Enter The Filename to Request : ");
    scanf("%s",fname);
    sendto(create_socket, fname, sizeof(fname), 0,(struct sockaddr *) &address,sizeof(address));
    printf("Request Accepted... Receiving File...\n\n");

    server_address_size=sizeof(server);


    printf("The contents of file are...\n\n");

    while((cont=recvfrom(create_socket, buffer, 10, 0,(struct sockaddr *) &address,sizeof(address)))>0) 
    {
        write(1, buffer, cont);
    }

    printf("\nEOF\n");
    return close(create_socket);
}

Where am i going wrong? Please provide a proper solution for the same.

Thanks in advance.

2
Very poor code. Instead of printing what happens in the success cases and ignoring the failure cases, you would be a lot better advised to check the failure cases and print errno or strerror or call perror(), so that you know about the failures. At present anything at all could be going wrong and you would never know. Printing things like 'request accepted' when what you have actually done is sent something, or 'connection accepted' when all you've done is created a connectionless socket, is equally senseless. - user207421
Also compile with all waring on, and fix the code then. - alk

2 Answers

2
votes

You are using the value-result arguments in recvfrom() wrong. A compiler should warn you about this very loudly. Recvfrom() will try to return a number to you in the 6th parameter, so you can not pass it a constant created with sizeof().

From the manpage:

The argument addrlen is a value-result argument, which the caller should initialize before the call to the size of the buffer associated with src_addr, and modified on return to indicate the actual size of the source address.

I changed the recvfrom() loop like this and a file was successfully sent & received.

int serv_addr_size = sizeof(address);
while((cont=recvfrom(create_socket, buffer, 10, 0,(struct sockaddr *) &address,&serv_addr_size))>0) 
{
    write(1, buffer, cont);
}

Since you are calling connect() on the socket, you could also use recv(), like so:

recv(create_socket, buffer, 10, 0)

As some general advice, allways carefully check the return values from system and library calls (except maybe for printf()) and be prepared for all cases listed on the functions man-page under "return values".

EDIT The server side makes a similar error in the other direction. A parameter of sendto() that should just be the length of the passed struct, is passed as a pointer.

sendto(create_socket,buffer,cont,0,(struct sockaddr *) &client,&client_address_size);

Should be

sendto(create_socket,buffer,cont,0,(struct sockaddr *) &client,client_address_size);
0
votes

Just let me to write a valid example. I've tried to rewrite your own code, but I prefer to show you a nice example. Just a few minutes...

---EDIT---

Ok, here I am. Forgive me for the time I spent, but I preferred to read carefully the code.

Here your two files:

Server implementation

Client implementation

Really hope I helped you.