More questions on sockets

John W. Baugh Jr. jwb at cepmax.ncsu.edu
Sat Jun 15 02:22:15 AEST 1991


I'm trying to write "send/receive"-like functions (i.e., send(msg,to),
receive(msg,from)) to hide some of the details of Internet stream
sockets for interprocessor communication (oh yeah, and I really don't
know what I'm doing).  Anyway, a couple of questions:

  - when trying to bind a stream socket I sometimes get an error
    "Address already in use", even though I've closed the socket
    (for example, when I run the program in succession a couple of
    times).  Is there something else I have to do?

  - assuming I'm on the right track (big assumption), is it possible
    to raise the level of abstraction of my send_msg/recv_msg
    functions.  For example, ideally one would like to do the
    following:
       send_msg(char *msg, int size, int process);
       recv_msg(char *msg, int size, int process);
     where "process" may be a process on any machine.  Okay, so that's
     probably asking too much.  What I currently have is:
       send_msg(char *msg, int size, char *hostname, int port);
       recv_msg(char *msg, int size, int port);
     Can one do better (w/o an inordinate effort)?

Any comments/suggestions/literature-ptrs would be welcomed.  Code
follows.

John Baugh
jwb at cepmax.ncsu.edu

-----------------------------------------------------------------------------
#include <sys/types.h>
#include <sys/socket.h>
#include <sys/time.h>
#include <netinet/in.h>
#include <netdb.h>
#include <stdio.h>

#define TRIES 10000

send_msg(char *msg, int size, char *hostname, int port)
{
  int sock;
  struct sockaddr_in server;
  struct hostent *hp, *gethostbyname();
  int i, connected = 0;

  hp = gethostbyname(hostname);
  if (hp == 0) {
    fprintf(stderr, "%s: unknown host", hostname);
    exit(2);
  }
  bcopy(hp->h_addr, &server.sin_addr, hp->h_length);
  server.sin_family = AF_INET;
  server.sin_port = port;

  for (i = 0; i < TRIES && !connected; i++) {

    sock = socket(AF_INET, SOCK_STREAM, 0);
    if (sock < 0) {
      perror("opening stream socket");
      exit(1);
    }

    if (connect(sock, &server, sizeof(server)) < 0)
      close(sock);
    else
      connected = 1;
  }

  if (!connected) {
    perror("connecting stream socket");
    close(sock);
    exit(1);
  }

  if (write(sock, msg, size) < 0)
    perror("writing on stream socket");
  close(sock);
  return 0;
}


recv_msg(char *msg, int size, int port)
{
  int sock, length;
  struct sockaddr_in server;
  int msgsock, rval;

  sock = socket(AF_INET, SOCK_STREAM, 0);
  if (sock < 0) {
    perror("opening stream socket");
    exit(1);
  }

  server.sin_family = AF_INET;
  server.sin_addr.s_addr = INADDR_ANY;
  server.sin_port = port;
  if (bind(sock, &server, sizeof(server))) {
    perror("binding stream socket");
    exit(1);
  }
  length = sizeof(server);
  if (getsockname(sock, &server, &length)) {
    perror("getting socket name");
    exit(1);
  }
  printf("Socket has port #%d\n", ntohs(server.sin_port));

  listen(sock, 5);
  msgsock = accept(sock, 0, 0);
  if (msgsock == -1)
    perror("accept");
  else {
    bzero(msg, size);
    if ((rval = read(msgsock, msg, size)) < 0)
      perror("reading stream message");
  }
  close(msgsock);
  close(sock);
      
  return 0;
}



More information about the Comp.unix.programmer mailing list