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