From: mread AT ozemail DOT com DOT au (Mark Read) Subject: Fw: Please review my Sockets() code, anyone? 11 Mar 1998 05:57:50 -0800 Message-ID: <00a901bd4c36$93d50c80$299f23cb.cygnus.gnu-win32@markread> Reply-To: "Mark Read" Mime-Version: 1.0 Content-Type: text/plain; charset="iso-8859-1" Content-Transfer-Encoding: 7bit To: Cc: I've re-posted this article in the hope someone will respond to me :-) I have a book on order about Unix Sockets programming (a reference from one of you good folk on this listserv - thanks Harry!), but can't wait 4-6 weeks for it's arrival !!! (I had to order from the US, as non of our Australian bookstores have it in stock - the book is "Unix Network Programming" by W.R.Stevens: Prentice Hall). Any help would be greatly appreciated. Mark. -----Original Message----- From: Mark Read To: gnu-win32 AT cygnus DOT com Date: Saturday, 7 March 1998 21:06 Subject: Please review my Sockets() code, anyone? >Hi. > >I've a very simple Server and Client Sockets() app that I've written. This >is my 1st attemp at such code. Both work when executed, and the Server >recognises when the Client talks to it, but I can't get either app to >read/send data. > >Could someone shed some light on what I'm doing wrong please? > >My environment: Win98 beta3, DOSBOX, GNU B18 (full cdk.exe). > >Both C files are compiled like so: > >c:\gnu\mark> gcc client1.c -oclient1.exe >c:\gnu\mark> gcc server4.c -oserver4.exe > >Both files are then executed in a separate DOSBOX (Server first, then >Client, of course). > >The Server can be terminated by pressing CTRL-C *then* running CLIENT1.EXE >I've tried to get signal() to recognise my ctrl-c trap when the user presses >ctrl-c, but my server app will only trap ctrl-c when it does something >(anything apparently). Given it's waiting on accept(), a client wanting to >connect triggers the accept() function, which triggers the ctrl-c trap >signal. Is it possible to trap ctrl-c immediately? > >By the way, I'm using Unix Sockets() as my aim is to port these apps >(eventually) across to SGI Irix, compile (hopefully without any code changes >required because I'm using standard Unix functions) and run them their. I do >not wish to write a Winsock app! > >Your help is sincerely appreciated. I'd be happy to donate my working source >code to the GNU web site (perhaps in a newbie section - refer to previous >email from me to this listserv entitled "mount, sh, bash, etc"). > > >Many thanks, Mark. > >PS: When you reply to this post, could you cc me too? Thanks :-) > > > > >*************************** >SERVER CODE >*************************** > >// ======================================= >// server4.c >// 27 feb 98 >// mark read >// cygnus gnc-win32 and socket programming >// ======================================= > >// includes >#include // for printf() >#include // for exit() > >#include >#include // for socket(), bind(), etc. >#include // for sockaddr_in structure >#include // for hostent structure >#include >#include // for sleep() > >// defines >#define MAXHOSTNAMELEN 128 >#define MAXBUFSIZE 1024 >#define PORTNO 8888 // we listen on this port number > >// prototypes >int main(void); >void handler(int sig); // exit here on op sys signal > >// global variables >int bEnd; > > >// ================================== >// Let's begin our testing of sockets >// programming under gnu-win32. >// ================================== >int main(void) >{ >// --------------------------- >// Order of socket processing: >// --------------------------- >// s = socket() >// bind(s) >// listen() then accept() >// send() or recv() >// close(s) > >int s, n, ns, len; >struct sockaddr_in address; // AF_INET sockaddr structure >struct hostent *host; // hostent structure >char buf[MAXBUFSIZE]; // holds data sent or rcvd > > >// ---------------- >// Welcome message. >// ---------------- >printf("\nSockets() test server app"); >printf("\nCopyright Mark Read, 1998"); >printf("\nCompiled with Cygnus GNU-Win32 b18\n"); > > >// --------------------------- >// Establish trapable signals. >// --------------------------- >signal(SIGQUIT, handler); // quit (ctrl-c?) >signal(SIGINT, handler); // interrupt (ctrl-c?) > > >// ---------------------------------------------------- >// Create socket and bind it to port and local machine. >// ---------------------------------------------------- >printf("\ncreating socket..."); >memset(&address, 0, sizeof(struct sockaddr_in)); // zero out memory for >address >address.sin_family = AF_INET; >address.sin_port = htons(PORTNO); // with local host info >if ((s = socket(AF_INET, SOCK_STREAM, 0)) < 0) // create the socket */ >{ > printf("failed"); > exit(-1); >} >else >{ > printf("ok"); >} > >printf("\nbinding socket to local machine and port..."); >if (bind(s, (struct sockaddr *) &address, sizeof(struct sockaddr_in)) < 0) >{ > printf("failed"); > return(-1); >} >else >{ > printf("ok"); >} > >// getsockname() > > >// ----------------------------------------------------------- >// Go into "listen" mode and await a connection from a client. >// ----------------------------------------------------------- >printf("\ncalling listen()..."); >if (listen(s, 5) == -1) >{ > printf( "error"); > exit(-1); >} >else >{ > printf("ok"); >} > >// now we wait for a caller >printf("\n\nlistening for a caller on port %d (press 'ctrl-c' to quit)...", >PORTNO); >bEnd = 0; >while (bEnd == 0) // this loop doesn't get executed until out 1st caller >calls >{ > //printf("\n sleeping..."); > //sleep(10); // allow ctrl-c to be trapped by signal > //printf("back from sleeping !!"); > if (bEnd == 1) break; > > // accept a connection if one in the queue > len = sizeof(struct sockaddr_in); > printf("\n calling accept()..."); > if ((ns = accept(s, (struct sockaddr *) &address, &len)) < 0) > { > printf("failed"); > break; > } > else > { > printf("ok"); > } > printf("\n ns=%d", ns); > > if (bEnd == 1) break; > > // Get all the client has to send us. > // Write it to stdout so human may see it. > //printf("\n-----------------"); > printf("\n\n rcvd from client: "); > > memset(&buf, 0, MAXBUFSIZE); > printf("\n strlen(buf)=%d", strlen(buf)); > > n = recv(s, buf, MAXBUFSIZE, 0); > printf("\n s=%d", s); > printf("\n n=%d", n); > printf("\n buf=[%s]", buf); > if (n > 0) printf("\n%d bytes rcvd", n); > > > // ********************************************** > // this works (doesn't crash system) > // but nothing is rcvd (well, nothing is printed) > while((n = recv(s, buf, MAXBUFSIZE, 0)) > 0) > { > //write(1, buf, n); > printf("\n s=%d", s); > printf("\n n=%d", n); > printf("\n buf=[%s]", buf); > //printf("%d bytes rcvd", n); > } > // ********************************************** > > > > //printf("\n-----------------"); > > // send a reply > printf("\n\n sending stuff to caller..."); > n = send(s, "hello", 5, 0); > printf("\n n = %d", n); > > printf("\n closing call..."); > close(ns); > > //printf("\n sleeping..."); > //sleep(1000); > //printf("back from sleeping !!"); > if (bEnd == 1) break; > printf("\n\nlistening for a caller on port %d (press 'ctrl-c' to >quit)...", PORTNO); >} > >printf("\nclosing socket..."); >close(s); > exit(0); >} > > >// ===================================================== >// If an op sys signal is rcvd (like ctrl-c) then abort. >// ===================================================== >void handler(int sig) >{ >bEnd = 1; >} > > > > > >*************************** >CLIENT CODE >*************************** > >// client1.c > >// Our Includes. >#include >#include >#include >#include >#include >#include >#include > >// Our Defines. >#define MAXBUFSIZE 1024 // buffer for sending and receiving data >#define PORTNO 8888 // server port to connect to >#define HOSTIP "127.0.0.1" // server is located here (local host) > >// Our Prototypes. >int main(int argc, char *argv[]); > > >// ========= >// Let's go! >// ========= >int main(int argc, char *argv[]) >{ >int n, s, len; >char buf[MAXBUFSIZE]; >struct sockaddr_in name; > >// do an argument check >// if(argc != 2) >// { >// fprintf(stderr, "Use: %s 'string'\n", argv[0]); >// exit(1); >// } > >// ---------------- >// Welcome message. >// ---------------- >printf("\nSockets() test client app"); >printf("\nCopyright Mark Read, 1998"); >printf("\nCompiled with Cygnus GNU-Win32\n"); > >// Create a socket in the INET domain. >printf("\ncreating socket..."); >if ((s = socket(AF_INET, SOCK_STREAM, 0)) < 0) >{ > printf("socket error (can't create a socket)"); > exit(1); >} > >// Create the address of the server we wish to talk to. >memset(&name, 0, sizeof(struct sockaddr_in)); >name.sin_family = AF_INET; >name.sin_addr.s_addr = inet_addr(HOSTIP); >name.sin_port = htons(PORTNO); > >// Connect to the server. >printf("\nconnecting to server %s on port %d...", HOSTIP, PORTNO); >if (connect(s, (struct sockaddr *) &name, sizeof(struct sockaddr_in)) < 0) >{ > printf("connect error (can't connect to server)"); > exit(1); >} > >// Copy the commandline argument to buf and send it to the server. >// strcpy(buf, argv[1]); >strcpy(buf, "hello"); >printf("\nsending [%s]...", buf); > if (send(s, buf, strlen(buf), 0) < 0) >{ > perror("send error"); > exit(1); >} >else >{ > printf("done"); >} > >// Get all the server has to send. >// Write to stdout. >printf("\nreceiving reply..."); > while((n = recv(s, buf, MAXBUFSIZE, 0)) > 0) > write(1, buf, n); > >printf("\nclosing socket...\n"); >close(s); // close socket >exit(0); // end app >} > - For help on using this list (especially unsubscribing), send a message to "gnu-win32-request AT cygnus DOT com" with one line of text: "help".