Re: [gtk-list] Re: gdk_add_input() Question



I found the problem.  The client was exiting, thus sending EOF, which
caused the problem.  I found the answer in the sockets FAQ.  Thanks
anyway.

Mike

On Sun, 10 Jan 1999, Mike Lindahl wrote:

> I have read the previous emails regarding gdk_add_input() and have tried
> to implement them.  It works just fine until I receive a message.  Then,
> it calls the function correctly, but then calls the function forever.  I
> call a recv() and it gets the message.  Then, it calls recv() the next
> time, but there is no data waiting, so recv returns an error.  What am I
> doing wrong??  Is there a problem with the way that the sockets are being
> set up??  I think that the problem only occurs on the server, but I am not
> sure of this.
> 
> Thanks
> Mike Lindahl
> 
> Here is the file that contains the setup for the sockets:
> 
> /*** 
>  *
>  *     Name:  simpsock.c
>  *
>  *   Author:  Ben Dressner -- thanks to all past administrators of CS217.
>  *  
>  *     Date:  Dec 16th, 1996.
>  *
>  *  Purpose:  establish a simple IPC system for cs217 -- Battleship 
>  *
>  ***/
> 
> #include <sys/types.h> /* required by socket.h */
> #include <sys/socket.h>
> #include <netinet/in.h>
> #include <arpa/inet.h>
> #include <netdb.h>
> #include <stdio.h> /* stderr */
> #include <assert.h> /* assert() */
> #include <stdlib.h> /* exit() */
> #include <strings.h> /* bzero() */
> #include <unistd.h> /* close() */
> 
> /* Added ML 1/10/98 */
> #include <sys/fcntl.h>
> 
> #include "simpsock.h"
> 
> #define SERVER 1
> #define CLIENT 0
> #define MAXQUEUE 1       /* we will only form one connection */
> 
> /***
>  *
>  *  setup
>  *
>  ***/
>  
> int setup(int process, char *hostname, short portno)
> {
>    int    cli_len;
>    int    sock_fd = 0, new_sock_fd = 0;
>    struct sockaddr_in  serv_addr, cli_addr;
>    struct hostent *hp;
>    
>    assert(process == SERVER || process == CLIENT);
>      
>    if (process == SERVER) {
>        if ((sock_fd = socket(AF_INET, SOCK_STREAM, 0)) < 0) {
>           fprintf(stderr, "server: can't open stream socket\n");
>           exit(1);
>        }
> 
>        bzero((char *) &serv_addr, sizeof (serv_addr) );      /* clear */
>        serv_addr.sin_family      = AF_INET;
>        serv_addr.sin_addr.s_addr = htonl(INADDR_ANY);
>        serv_addr.sin_port        = htons(portno); 
>       
>        if (bind(sock_fd,(struct sockaddr *) &serv_addr,sizeof(serv_addr)) == -1) {
>            fprintf(stderr, "server: can't bind socket\n");
>            close(sock_fd);
>            exit(1);
>        }
>  
>        if (listen(sock_fd, MAXQUEUE) == -1) {
>            fprintf(stderr, "server: can't listen\n");
>            exit(1);
>        }
>  
>        cli_len     = sizeof(cli_addr);
>        new_sock_fd = accept(sock_fd, (struct sockaddr *)&cli_addr, &cli_len);
> 
>        if (new_sock_fd < 0) {
>            fprintf(stderr, "server: accept error\n");
>            exit(1);
>        }
>        
> /* Added ML 1/10/98 */
>        if( fcntl(sock_fd, F_SETFL, O_NONBLOCK) )
>        {
> 	    fprintf(stderr, "server: couldn't set non-blocking flag\n");
> 	    exit(1);
>        }
> 
>        close(sock_fd);
>        return new_sock_fd;
>    }
> 
>    if (process == CLIENT) {
>        hp = gethostbyname(hostname);
>        bcopy(hp->h_addr,&serv_addr.sin_addr, hp->h_length);
>        serv_addr.sin_family      = hp->h_addrtype;
>        serv_addr.sin_port        = htons(portno);
>  
>        if ( (sock_fd = socket(hp->h_addrtype, SOCK_STREAM, 0)) < 0) {
>            fprintf(stderr, "client: socket error\n");
>            exit(1);
>        }
>       
>        if (connect(sock_fd,(struct sockaddr *)&serv_addr,sizeof(serv_addr))< 0) {
>            fprintf(stderr, "client: can't connect -- server may be down\n");
>            exit(1);
>        }
> 
> /* Added ML 1/10/98 */
>        if( fcntl(sock_fd, F_SETFL, O_NONBLOCK) )
>        {
> 	    fprintf(stderr, "server: couldn't set non-blocking flag\n");
> 	    exit(1);
>        }
> 
>        return sock_fd;
>    }
>    return -1;  /* error if you get here */
>    
> }  /* END SETUP */ 
> 
> 
> 
> /***
>  *
>  *  SendMessage
>  *
>  ***/
> 
> void SendMessage(int SocketDescriptor, char *buf) 
> {
>    assert(buf);
>    assert(strlen(buf) < MAXMESSAGE);
>    send(SocketDescriptor,buf,strlen(buf)+1,0);
> }
> 
> 
> /***
>  *
>  *  ReceiveMessage
>  *
>  ***/
> 
> int ReceiveMessage(int SocketDescriptor, char *buf) 
> {
>    assert(buf);
>    return recv(SocketDescriptor,buf,MAXMESSAGE,0);
> }
> 
> 
> On Sat, 9 Jan 1999, Jan Kratochvil wrote:
> 
> > > G'Day,
> > Hi
> > 
> > > I've come across a small hurdle with the use of gdk_add_input().
> > > 
> > > To simplify the whole problem I wrote an application which shows the
> > > behaviour and it is available at:
> > > 	http://www.uq.net.au/~zzcprows/development/
> > 
> >   I haven't tested it exactly in your program but I have very bad
> > experience with using real PIPES and do non-blockng I/O on them. Facts:
> > 
> > 1) You NEED non-blocking I/O. Otherwise you would have to rely on GTK's
> >    select()/poll() behaviour and do kernel read() of 1 (only 1!) byte
> >    and thats' overkill - it would need userlevel/supervisor kernel switch
> >    on each byte of input/output data. Otherwise when there is ready only
> >    1 byte ready in the queue and you would do a read of 2, it simply blocks.
> > 
> > 2) Turning PIPE to non-blocking mode:
> > 
> > ----------------------------------------------------------------------------
> > void nonblock(int fd,const char *name)
> > {
> >   if (fcntl(fd,F_SETFL,O_NONBLOCK))
> >     FATAL(ERR,"fcntl(%s,non-blocking): %m",name);
> > }
> > ----------------------------------------------------------------------------
> > 
> >    will cause to turn to non-blocking mode even the other side of the
> >    pipe. Normal applications are simply not ready for non-blocking
> >    behaviour of their stdio (and aren't expected/shouldn't be prepared
> >    for that, that's OK).
> >    This both-side non-blocking switch behaviour was seen on some Linux
> >    at least.
> > 
> > 3) Using UNIX domain socketpair() works as expected for me. Drop that
> >    pipes, they're useless. I just hope that my employer doesn't kick
> >    me for revealing a part of non-GPLed code :-) :
> > 
> > ----------------------------------------------------------------------------
> > int upsetupconn(const char *host,const char *userorport)
> > {
> > int sock;
> > 
> >   if (1) {
> > #if 0
> > /* hasn't worked */
> > int pair[2][2],i;
> >     for (i=0;i<2;i++)
> >       if (pipe(pair[i]))
> >         FATAL(CRIT,"pipe(): %m");
> > #endif
> > int socks[2],rc;
> >     if (socketpair(AF_UNIX,SOCK_STREAM,0,socks))
> >       FATAL(CRIT,"socketpair(AF_UNIX,SOCK_STREAM,0): %m");
> >     assert(!upsc_sshchildpid);
> >     if (!(upsc_sshchildpid=fork())) { /* SSH client */
> >       if (dup2(socks[1],STDIN_FILENO)!=STDIN_FILENO)
> >         FATAL(CRIT,"In ssh-client process dup2(sock,STD%s): %m","IN");
> >       if (dup2(socks[1],STDOUT_FILENO)!=STDOUT_FILENO)
> >         FATAL(CRIT,"In ssh-client process dup2(sock,STD%s): %m","OUT");
> >       if (close(socks[1]))
> >         FATAL(CRIT,"In ssh-client process close(sock): %m");
> > #define SSHARGS upsc_sshpath,upsc_sshpath,"-l",userorport, \
> >   "-o","BatchMode yes", \
> >   "-o","EscapeChar none", \
> >   "-o","FallBackToRsh no", \
> >   "-o","StrictHostKeyChecking yes", \
> >   "-o","UseRsh no", \
> >   host,M1D_BOGUS_SSH_ARG
> > #define SSHARGF "execl(\"%s\",\"%s\",\"%s\",\"%s\",\"%s\",\"%s\",\"%s\",\"%s\",\"%s\",\"%s\",\"%s\",\"%s\",\"%s\",\"%s\",\"%s\",\"%s\")"
> > 
> >       dbg("client: executing " SSHARGF,SSHARGS);
> >       rc=execl(SSHARGS,NULL);
> >       FATAL(ERR,"In ssh-client process " SSHARGF " returned %d: %m",SSHARGS,rc);
> >       }
> >     sshchildfd=sock=socks[0];
> > #if 0
> >     write(socks[0],"blabol\n",7);
> >     read(socks[0],buf,7);
> >     printf("got:%s\n",buf);
> >     FATAL(DEBUG,"DEBUG finish");
> > #endif
> >     }
> >   nonblock(sock,"sock");
> >   return(sock);
> > }
> > ----------------------------------------------------------------------------
> > 
> > 
> > 
> > 						Lace
> > 
> > -- 
> > To unsubscribe: mail -s unsubscribe gtk-list-request@redhat.com < /dev/null
> > 
> > 
> 
> -- 
> To unsubscribe: mail -s unsubscribe gtk-list-request@redhat.com < /dev/null
> 
> 



[Date Prev][Date Next]   [Thread Prev][Thread Next]   [Thread Index] [Date Index] [Author Index]