BSD Sockety a funkce select()
Ladislav Vaiz
spam na nagano.cz
Úterý Červenec 1 12:46:05 CEST 2008
Zdravim,
neanalyzoval jsem to do detailu, tak se treba mylim:
1) FD_ZERO je na miste
2) FD_SET(sock /* =server.sock */ ) take
Select() vam sock_set cely predela podle toho, jake udalosti nastaly.
Musite ho vytvorit znovu nebo si ho pamatovat.
Kdyby vam to neslo ani tak, poslete vystup strace.
Lada
Antonín Kolísek napsal(a):
> 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.
>
> _______________________________________________
> Linux mailing list
> Linux na linux.cz
> http://www.linux.cz/mailman/listinfo/linux
>
Další informace o konferenci Linux