Sponsored Content
Top Forums UNIX for Advanced & Expert Users HOW to create UDP Concurrent Server Post 302187473 by ramen_noodle on Monday 21st of April 2008 07:04:44 AM
Old 04-21-2008
Please take a look at the tftpd source at:
Inetutils - GNU internet utilities.

There are numerous non-trivial problems with using udp concurrently and reliably.
As an exercise this threaded example which is pretty broken.
Code:
#include <stdio.h>
#include <stdlib.h>
#include <string.h>
#include <unistd.h>
#include <sys/types.h>
#include <sys/socket.h>
#include <netinet/in.h>
#include <arpa/inet.h>
#include <signal.h>
#include <sys/select.h>
#include <fcntl.h>
#include <pthread.h>

int numthreads = 0;
pthread_mutex_t threadwatch = PTHREAD_MUTEX_INITIALIZER;
char *OOSMSG = "Maximum connections exceeded.\n";

#define noblock(sck) (fcntl(sck,F_SETFL,O_NONBLOCK)) 
#define DSZ 256
#define ACREDLEN 20
#define MAXTHREADS 20


typedef struct _assoc_data_ {
int msgnum;
short data_type_id;
char reserved;
char assoc_auth_creds[ACREDLEN];
char data[DSZ];
} APKT; 

void decrement_threadcount(void) {
                   pthread_mutex_lock(&threadwatch);
                   numthreads--;
                   pthread_mutex_unlock(&threadwatch);
}

void increment_threadcount(void) {
                pthread_mutex_lock(&threadwatch);
                numthreads++;
                pthread_mutex_unlock(&threadwatch);
}

void print_apkt(APKT dta) {

               printf("Msgnum = %d, data_type_id = %d,reserved = %c\n \
                      assoc_auth_creds = %s, data = %s\n",dta.msgnum,dta.data_type_id,dta.reserved,dta.assoc_auth_creds,dta.data);
}
                       
void *handleclient(void *sck) {
int privsock, tsz, sock;
short syn_ack = 0x11;
APKT rdata;
struct sockaddr_in relation, peer;

                pthread_detach(pthread_self());
                memcpy(&sock,sck,sizeof(sock));
                bzero(&rdata,sizeof(rdata));
                tsz = sizeof(relation);

                
                increment_threadcount();
                /*reading data like the below is broken across various machine specific boundaries, byte ordering, word size, etc..buyer beware*/
                if (recvfrom(sock,&rdata,sizeof(rdata),0,(struct sockaddr *)&relation,&tsz) <= 0) {
                   perror("recvfrom()");
                   decrement_threadcount();
                   pthread_exit(NULL);
                }

                print_apkt(rdata);
                if ( (privsock = retudpsrv("0.0.0.0",0)) < 0) {decrement_threadcount(); pthread_exit(NULL);}
                /*for udp concurrency one should bind an ephemeral port and re-negotiate with the client for communication on the new port->address. One should also find the interface 
                 that the original packet arrived on and only bind this address. */
                noblock(privsock);
                sendto(privsock,&syn_ack,sizeof(syn_ack),0,(struct sockaddr *)&relation,tsz); /*acknowledge data receipt*/
                /*process data in rdata, verify peer credentials and transaction signature/viability and finally send back result to client here*/
                close(privsock);
                decrement_threadcount();
                pthread_exit(NULL);
}
                      

int retudpsrv(char *addr, int pno) {
int sck, option = 1;
struct sockaddr_in srv;

             bzero(&srv,sizeof(srv));
             srv.sin_addr.s_addr = inet_addr(addr);
             srv.sin_port = htons(pno);
             srv.sin_family = AF_INET;
       
             if ( (sck = socket(AF_INET,SOCK_DGRAM,0)) < 0) {
                perror("socket()");
                return -1;
             }

             setsockopt(sck,SOL_SOCKET, SO_REUSEADDR, (void *)&option, sizeof(option));
            /*could and should use IP options for IF and RECVADDR here for recvmsg, but this is more complicated than desirable for an example*/
             noblock(sck);
             
             if (bind(sck,(struct sockaddr *)&srv,sizeof(srv)) < 0) {
                perror("bind()");
                return -1;
             }
             return sck;
}

int main(int argc, char **argv) {
int vopt,sock;
fd_set fds;
pthread_t tids[MAXTHREADS];


           if (argc != 3) {printf("Please specify:\n1) Address to bind\n2)Port number to bind\n"); exit(1);}
           if ( (sock = retudpsrv(argv[1],atoi(argv[2]))) < 0) {return -1;}
           
           FD_ZERO(&fds);
           FD_SET(sock,&fds);
           noblock(sock);

          while (1) {
                    if ( (vopt = select(sock + 1,&fds,NULL,NULL,NULL)) < 0) {
                       perror("select()");
                       return  -1;
                    }
                    /*select may return a number of times before data becomes available to the client handler..this causes multiple thread creation
                     and overhead..with non-blocking i/o and quick exits for bad reads it's fairly painless but this is still bad design in a production
                    server*/ 
                    if (numthreads >= MAXTHREADS) {continue;}
                    pthread_create(&tids[numthreads],NULL,handleclient,(void *)&sock);
                    printf("Currently handling client. %d threads in use.\n",numthreads);
          }
}


Last edited by ramen_noodle; 04-21-2008 at 10:42 AM..
 

10 More Discussions You Might Find Interesting

1. IP Networking

concurrent udp server

Just like concurrent tcp server, anyone know how to design the concurrent udp server with the thread? it's best to give some basic examples,thanks (0 Replies)
Discussion started by: Frank2004
0 Replies

2. Programming

Print server via UDP

Hello, I would like to ask you for a help. I need to program in C print server which is based on connectionless protocol UDP. The problem is that I am not experienced in programming network applications, I can help myself with some other answered questions on this forum about network apps in C,... (1 Reply)
Discussion started by: samciz
1 Replies

3. UNIX for Dummies Questions & Answers

How can I check UDP connection to other server?

Hi, My network dep. telles me that they have opened the FW but my application still can not get through to other server. If it was TCP I could simply test it myself with "telnet", but how can I check it when the connection is UDP? Tnx (1 Reply)
Discussion started by: mehrdad68
1 Replies

4. UNIX for Dummies Questions & Answers

UDP server on Solaris 9

So I am attempting to implement a UDP server on an older Solaris 9 box; the server will be handling packets at a rate of about 12/sec and will be constructing acknowledgment messages on the fly. I've found snippets of sample code here and there on the net... should I be writing this from scratch... (1 Reply)
Discussion started by: allbread
1 Replies

5. Programming

Concurrent TCP client/server

I made a program and now I need to make it concurrent. Can someone pls help me do this ? The code is this: #include <sys/types.h> #include <sys/socket.h> #include <sys/time.h> #include <netinet/in.h> #include <errno.h> #include <unistd.h> #include <stdio.h> #include <string.h>... (4 Replies)
Discussion started by: Johnny22
4 Replies

6. Programming

Unable to create a UDP client from thread?

I try to initial a UDP client from threading, but it doesn't work? why? These codes from the textbook #define ECHOMAX 255 /* Longest string to echo */ #define TIMEOUT_SECS 2 /* Seconds between retransmits */ #define MAXTRIES 5 /* Tries before giving up */... (3 Replies)
Discussion started by: sehang
3 Replies

7. IP Networking

How to create a multi-chat server using UDP?

Hifriends I have a doubt . how to create a multi-chat server using UDP which can run on MAC systems.. Thank u in advance (3 Replies)
Discussion started by: babbu25
3 Replies

8. UNIX for Advanced & Expert Users

Problem with simple concurrent server example

hi all my problem is i have programmed a server to accept multiple clients through concurrent server approach https://lh3.googleusercontent.com/-hg-TSMdDj1k/UG5R7iICXaI/AAAAAAAAC5M/23_NnU5kH94/s800/concserver.png but when i try to execute the binding and connection accept works fine but the... (1 Reply)
Discussion started by: shyam.sunder91
1 Replies

9. Programming

Clients - Server ( UDP )

Hello, I have a question: I want to create a n client to one server connection. This is the client-server algorithm. Enybody help to make the changes? (0 Replies)
Discussion started by: MaHmur
0 Replies

10. AIX

Difference between concurrent and enhanced concurrent VG

Hi, What are the differences between concurrent and enhanced concurrent VGs.? Any advantages of enhanced concurrent VG over normal concurrent vg Regards, Siva (2 Replies)
Discussion started by: ksgnathan
2 Replies
All times are GMT -4. The time now is 02:21 PM.
Unix & Linux Forums Content Copyright 1993-2022. All Rights Reserved.
Privacy Policy