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