Subject: Fw: Please review my Sockets() code, anyone?
From: [email-masked] (Mark Read)

11 Mar 1998 05:57:50 -0800
Message-ID: <00a901bd4c36$93d50c80$299f23cb.cygnus.gnu-win32@markread>
Reply-To: "Mark Read" <[email-masked]>
Mime-Version: 1.0
Content-Type: text/plain;
	charset="iso-8859-1"
Content-Transfer-Encoding: 7bit
To: <[email-masked]>
Cc: <[email-masked]>

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 <[email-masked]>
To: [email-masked] <[email-masked]>
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 <stdio.h>  // for printf()
>#include <stdlib.h>  // for exit()
>
>#include <sys/types.h>
>#include <sys/socket.h>  // for socket(), bind(), etc.
>#include <netinet/in.h>  // for sockaddr_in structure
>#include <netdb.h>  // for hostent structure
>#include <signal.h>
>#include <unistd.h>  // 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 <stdio.h>
>#include <sys/types.h>
>#include <sys/socket.h>
>#include <netinet/in.h>
>#include <string.h>
>#include <stdlib.h>
>#include <signal.h>
>
>// 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
"[email-masked]" with one line of text: "help".