views:

581

answers:

4

I'm working on a homework problem for class. I want to start a UDP Server that listens for a file request. It opens the file and sends it back to the requesting client with UDP.

Heres the server code.

    // Create UDP Socket
    if ((sockfd = socket(AF_INET, SOCK_DGRAM, 0)) == -1) {
     perror("Can't create socket");
     exit(-1);
    }

    // Configure socket
    memset(&server, 0, sizeof server);
    server.sin_family = AF_INET; // Use IPv4
    server.sin_addr.s_addr = htonl(INADDR_ANY); // My IP
    server.sin_port = htons(atoi(argv[1])); // Server Port

    // Bind socket
    if ((bind(sockfd, (struct sockaddr *) &server, sizeof(server))) == -1) {
     close(sockfd);
     perror("Can't bind");
    }

    printf("listener: waiting to recvfrom...\n");
    if (listen(sockfd, 5) == -1) {
     perror("Can't listen for connections");
     exit(-1);
    }

while (1) {
 client_len = sizeof(struct sockaddr_in);
 newsockfd = accept(sockfd, (struct sockaddr*)&client,&client_len);

 if (newsockfd < 0) {
  perror("ERROR on accept");
 }

 // Some how parse request
 // I do I use recv or recvfrom?
 // I do I make new UDP socket to send data back to client?

 sendFile(newsockfd, filename);

 close(newsockfd);
}

close(sockfd);

I'm kind of lost how do I recv data from the client? And how to I make a new UDP connection back to the client?

Thanks!

+4  A: 

You should consult Beej's Guide to Network Programming. It goes into great detail on the basics of network programming. It covers the system calls in chapter 5, which is where you will find information on recv and recvfrom.

James McNellis
I would not recommend beejs, the examples doesn't even handle the fact that TCP is not message oriented, but a stream.
leeeroy
He has a good example on UDP at the bottom but its a one way send/recv. I need the server to talk back to the client. If there was another example online that would be awesome.
Bernie Perez
+2  A: 

Keep in mind that UDP is connectionless. It only sends packets, and is not suitable for sending files - unless the entire content fit in one UDP packet.

If you anyway want to send/receive UDP packets, you simply call sendto/recvfrom with the appropriate addresses.

leeeroy
nothing wrong with using UDP to build a protocol on.
Hassan Syed
The next part is break up the file into multiple parts and send it using SR or GBN.
Bernie Perez
+1  A: 

accept is only used for connection oriented (STREAM) sockets. UDP is not stream, oriented, so there are no connections and you can't use accept(2) -- it will return EOPNOTSUPP.

Instead, you just read packets directly from the bound service socket (generally using recvfrom(2) so you can tell where thy came from, though you can use recv or just read if you don't care), afterwhich you can send packets back using the same socket (and generally using sendto(2))

Chris Dodd
Thanks, this was the most helpful for my problem. If no one has a good example I could follow, this will be the accepted answer.
Bernie Perez
A: 

How UDP is different from TCP:

  • message-oriented, not stream-oriented. You don't read/write or send/recv. You sendto/recvfrom. The size of message is limited to 64K. Each call to recvfrom gets one message sent by a call to sendto. If recvfrom passes a buffer that's smaller than the size of message, the rest of message is gone for good.

  • no connections. Therefore no listen/accept/connect. You send a message to a particular address/port. When you receive message (on the address/port to which your socket is bound), you get the source of the incoming message as an output parameter to recvfrom.

  • no guarantees. The messages can be dropped or received out of order. If I remember correctly, they cannot be truncated, though.

One last word of caution - you may find yourself re-inventing TCP over UDP. In that case, stop and go back to TCP.

Arkadiy
That is the point. Its not a complete re-inventing of TCP, its just the RDT, not congestion control or any of the other features of TCP.
Bernie Perez
Just be dead sure you don't need the features of TCP you're leaving behind.
Arkadiy