Path: utzoo!utgpu!news-server.csri.toronto.edu!cs.utexas.edu!asuvax!ncar!gatech!taco!cepmax.ncsu.edu!jwb From: jwb@cepmax.ncsu.edu (John W. Baugh Jr.) Newsgroups: comp.unix.programmer Subject: More questions on sockets Message-ID: <1991Jun14.162215.14657@ncsu.edu> Date: 14 Jun 91 16:22:15 GMT Sender: news@ncsu.edu (USENET News System) Reply-To: jwb@cepmax.ncsu.edu Organization: North Carolina State University Lines: 121 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@cepmax.ncsu.edu ----------------------------------------------------------------------------- #include #include #include #include #include #include #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; }