Re: [gtk-list] Re: gdk_add_input() Question
- From: Mike Lindahl <mlindahl phoenix Princeton EDU>
- To: gtk-list redhat com
- Subject: Re: [gtk-list] Re: gdk_add_input() Question
- Date: Sun, 10 Jan 1999 20:54:37 -0500 (EST)
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
>
>
[
Date Prev][
Date Next] [
Thread Prev][
Thread Next]
[
Thread Index]
[
Date Index]
[
Author Index]