开发者

Multi-threaded udp server/client

I just created a little reliable file transfer using udp but it only handles one client. So I thought about using fork() to get the server to handle multiple clients. But, i don't really know how to proceed. For now, I know I don't need to change the client side and the server is the one that will do the dirty work. Any thought/ideas on how to tackle that problem is greatly appreciated. Ps. here is how I started:

 void sigchldAction(int sig) {
 while (waitpid(-1, 0, WNOHANG) > 0) {
     ;
 }int main(int argc, char *argv[]) {

 return;
} //This is my function that waits for all the processes 

Here is my server:

int main(int argc, char *argv[]) {
    struct sockaddr_in serv_addr;
    int port_number, socket_fd;
    port_number = atoi(argv[1]);

    signal(SIGCHLD, sigchldAction);

    if ((socket_fd = socket(AF_INET, SOCK_DGRAM, 0)) < 0)  exit(EXIT_FAILURE);
    if (setsockopt(socket_fd, SOL_SOCKET, SO_REUSEADDR,
 (const void *)&optval, sizeof(int)) < 0) exit(EXIT_FAILURE);

    bzero((void *)&serv_addr, sizeof(struct sockaddr_in));
    serv_addr.sin_family = AF_INET;
    serv_addr.sin_addr.s_addr = htonl(INADDR_ANY);
    serv_addr.s开发者_C百科in_port = htons(port_number);
    if (bind(socket_fd, (struct sockaddr *)&serv_addr,
         sizeof(struct sockaddr_in)) < 0) exit(EXIT_FAILURE);

    pid_t child_pid;
    while (1) {
    child_pid = fork();

    switch (child_pid) {
        case -1:
            perror("Fork() Failed. \n");
            exit(EXIT_FAILURE);
            break;
        case 0:
            process_request(socket_fd);
            exit(EXIT_SUCCESS);
            break;
        case 1:
            close(socket_fd);
            break;

    } 

}
    close(socket_fd);
exit(EXIT_SUCCESS);
}

Then my process_request function takes care of any incoming data.


If you're using UDP you don't have a connection; it's a connectionless protocol.

If you're going to fork, you'd need to do what ftpd does and tell the remote client to send the forked child packets on a different port than the original one (and of course have the child receive on that port).


You're better off avoiding fork(), and simply distinguishing the clients based on their source address.

The basic approach to take is to take all of your variables that currently describe the application-layer connection (eg. current file, current position within the file, client address) and hoist those into a struct. You then create one instance of this struct per client.

Use recvfrom() rather than recv() to listen for incoming packets. This will supply the client's address (note that address in this sense should include the client's port number) - you can then look up the appropriate instance of the per-client struct.

0

上一篇:

下一篇:

精彩评论

暂无评论...
验证码 换一张
取 消

最新问答

问答排行榜