BSD Sockety a funkce select()

Antonín Kolísek antonin.kolisek na centrum.cz
Úterý Červenec 1 11:26:13 CEST 2008


Dobry den,
 
 cely den se marne snazim rozbehnout jeden program, aby pracoval jako 
klient/server
(lokalni socket). Program obslouzi jen prvniho klienta a druhy se k nemu 
vubec nepripoji.

Nerad bych se priklanel k reseni pomoci podprocesu (fork(),...) a vlakna 
nepripadaji vubec v uvahu.
Vim ze to musi jit nejak pomoci fce select(),ale proste se mi to nedari. 
Pripadne mi to jako bych
pri spojeni (accept()) zapomel nebo si prepsal puvodni socket vytvoreny 
serverem...

Pokud by nekdo vedel kde delam chybu velmi by mi to pomohlo. Uvadim zde 
kratky priklad
na kterem sve kroky testuji.

*********** server.c *************
#include <stdio.h>
#include <stdlib.h>
#include <errno.h>
#include <string.h>
#include <fcntl.h>
#include <sys/types.h>
#include <sys/socket.h>
#include <sys/un.h>


#define SOCK_PATH "socket"

struct server_sock {
    int sock; /*socket serveru*/
    int sock_c[256]; /*klientske sockety*/
    int len; /*velikost vyhrazene pameti*/
    int t;
    int n; /*pocet klientskych socketu*/
    struct sockaddr_un local, remote;
};

struct server_sock create_sock(void);

struct server_sock create_sock(void)
{
struct server_sock server;
char str[100];

    if ((server.sock = socket(PF_UNIX, SOCK_STREAM, 0)) == -1)
    {
        fprintf(stdout, "socket : %s\n",strerror(errno));
        exit(1);
    }

    server.local.sun_family = PF_UNIX;

    strcpy(server.local.sun_path, SOCK_PATH);
    unlink(server.local.sun_path);

    server.len = strlen(server.local.sun_path) + 
sizeof(server.local.sun_family);

    if (bind(server.sock, (struct sockaddr *)&server.local, server.len) 
== -1)
    {
        fprintf(stdout, "bind : %s\n",strerror(errno));
        exit(1);
    }

    if (listen(server.sock, 10) == -1)
    {
        fprintf(stdout, "listen on server socket : %s\n",strerror(errno));
        exit(1);
    }

    return(server);
}

int main(void)
{
struct server_sock server;
char str[100];
int i = 0, n;
int sockn = 0;
int len;
int sock;
fd_set sock_set;

    /*vytvoreni socketu*/
    server = create_sock();

    sock = server.sock;

    //tv.tv_sec = 3;
    //tv.tv_usec = 0;

    printf("Cekam na spojeni...\n");

    len = sizeof(server.remote);

    FD_ZERO(&sock_set);
    FD_SET(sock, &sock_set);

    while (1)
    {
        //FD_ZERO(&sock_set);
        //FD_SET(sock, &sock_set);

        for (i = 0; i < sockn; i++)
            FD_SET(server.sock_c[i], &sock_set);
       
        if (select(sock + 1, &sock_set, NULL, NULL, NULL) < 0)
        {
            fprintf(stdout, "select : %s\n",strerror(errno));
            close(server.sock);
            unlink(SOCK_PATH);
            exit(1);
        }

         if (FD_ISSET(server.sock, &sock_set))
        {
            len = sizeof(server.remote);

            if ((server.sock_c[sockn] = accept(server.sock, (struct 
sockaddr *)&server.remote, &len)) == -1)
            {
                fprintf(stdout, "accept : %s\n",strerror(errno));
                close(server.sock);
                unlink(SOCK_PATH);
                exit(1);
            }

            FD_SET(server.sock_c[sockn], &sock_set);
            server.n = sockn++;

            fprintf(stdout, "Connected.\n");
        }

        for (i = 0; i < sockn; i++)
        {
            if (FD_ISSET(server.sock_c[i], &sock_set))
            {
                n = recv(server.sock_c[i], str, 100, 0);
                if (n <= 0)
                {
                    fprintf(stdout, "recv : %s\n",strerror(errno));
                    FD_CLR(server.sock_c[i], &sock_set);
                    close(server.sock_c[i]);
                    exit (1);
                }

                printf("DDD: send\n");
                if (send(server.sock_c[i], str, n, 0) <= 0)
                {
                    fprintf(stdout, "send : %s\n",strerror(errno));
                    close(server.sock_c[i]);
                    exit (1);
                }
            }
        }
        printf("go to back  - select\n");
    }

    close(server.sock);
    unlink(SOCK_PATH);

    return (0);
}

*************konec****************

Omlouvam se za delku prikladu, ale pro nazornost jej posilam cely.
Dekuji za kazdou radu.

A.K.




Další informace o konferenci Linux