My problem with fdopen and sockets........

Arup Mukherjee arup at grad1.cis.upenn.edu
Tue Feb 14 07:12:22 AEST 1989


To all net.wizards [again...] :

   I had 3 responses to my earlier posting asking how to obtain a FILE *
that would allow bidirectional communication over an internet socket.
Well, I had 3 responses and they all suggested that I dup() the fd and
use one for reading and the other for writing. As I indicated in my
earlier posting, this does not work. 

Enclosed below are two program listings. writer.c waits for a
connection, writes some stuff to it, and then trys to read something.
reader.c connects to the write, reads some stuff and then writes some
stuff. These work fine using read() and write() calls. However, when I
substitute equivalent fprintf and fscanf calls (by using -DPRINTF or
-DSCANF from the command line while compiling), nothing works.

Again, any suggestions will be greatly appreciated....


						Arup Mukherjee
					[arup at grasp.cis.upenn.edu]

---writer.c---

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


int sock, i, newsock, j, sock2;
char *ptr;
char buf[1024];
char *buf2;
extern int errno;

cleanup ()
{
	shutdown(sock, 2);
	shutdown(sock2, 2);
	shutdown (newsock, 2);
	printf ("writer : exiting\n");
	exit(0);
}

main (argc, argv)
char **argv;
{

	struct sockaddr_in sa;
	struct hostent *host;
	FILE *in, *out;


	host = (struct hostent *) gethostbyname("localhost");
	bzero (&sa, sizeof(struct sockaddr_in));

	sa.sin_family = AF_INET;
	bcopy (host->h_addr, &sa.sin_addr, host->h_length);
	sa.sin_port = 7000;
	

	sock = socket (AF_INET, SOCK_STREAM, 0);
	bind (sock, &sa, sizeof(struct sockaddr_in));
	perror ("bound socket...");
	listen (sock, 3);
	newsock = accept(sock, &buf2, &j);
	fprintf (stderr,"writer : Connected %s %d : %d\n", buf2, j, newsock);
	
	for (i = 0; i< 20; ++i) signal (i, cleanup);

	sock2 = dup(newsock);
	out = fdopen (newsock, "w");
	in = fdopen (sock2, "r");

	for (i=0;i < 3;i++){

		errno = 0;
		sprintf (buf, "Testing : %d", i);

# ifdef PRINTF
		fprintf(out, "%s\n", buf); 
# else
		write (newsock, buf, strlen(buf) + 1);
# endif
		if (errno) perror("Writer Error :");
	}


# ifdef SCANF
	fscanf(in, "%s", buf);
# else
	read (newsock, buf, 30);
# endif

	fprintf(stderr, "writer reads: %s\n", buf);

	cleanup();
}




--- reader.c ---

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


int sock, i, sock2;
char *ptr;
char buf[1024];
extern int errno;

cleanup ()
{
	shutdown(sock, 2);
	shutdown(sock2, 2);
	printf ("reader : exiting\n");
	exit(0);
}

main (argc, argv)
char **argv;
{
	struct sockaddr_in sa;
	struct hostent *host;
	FILE *in, *out;

	host = (struct hostent *) gethostbyname("localhost");
	bzero (&sa, sizeof(struct sockaddr_in));

	sa.sin_family = AF_INET;
	bcopy (host->h_addr, &sa.sin_addr, host->h_length);
	sa.sin_port = 7000;
	

	sock = socket (AF_INET, SOCK_STREAM, 0);
	connect (sock, &sa, sizeof(struct sockaddr_in));

	if (errno) perror ("Reader Error :");
	
	for (i = 0; i< 20; ++i) signal (i, cleanup);

	sock2 = dup(sock);

	in = fdopen(sock, "r");
	out = fdopen (sock2, "w");
	for (i=0; i < 3 ;i++){

# ifdef SCANF
		fscanf (in,  "%s", buf); 
# else 
		read (sock, buf, 12);
# endif
		
		fprintf (stderr,"reader reads :%s\n", buf);
	}

	sprintf (buf, "Hi there, this is the reader\n");

# ifdef PRINTF
	fprintf(out, "%s\n", buf);
# else
	write (sock2, buf, strlen(buf)+1);
# endif

	fprintf (stderr, "reader : done writing %d chars\n", strlen(buf) + 1);
	cleanup();
}



More information about the Comp.unix.wizards mailing list