View Full Version : fprintf on a socket
bsd_newbie
February 12th, 2009, 01:35
I have some code that is sending output to stdout. I'd like to send
it over a socket. Can I cast the socket descriptor to FILE * using fdopen and call fprintf with FILE * as the first parameter.
thanks.
bsd_newbie
Djn
February 12th, 2009, 02:07
I would expect so - if it looks like a file, you should be able to treat it as one.
Try?
dh
February 12th, 2009, 12:09
No you can't do such thing, FILE is a struct and not a int like socket descrioptors are.
You could however associate a FILE struct with descriptor using fdopen() function:
int fd = socket(AF_INET, SOCK_STREAM, 0);
FILE *fp = fdopen(fd, "r+");
However, I would take another path and use snprintf() to format string and use regular write() call to send it.
dh
February 12th, 2009, 12:21
Oh nevermind, I didn't read orignal post carefully enough... you already mentioned fdopen().
anemos
February 12th, 2009, 13:02
You can do close(1); which will free stdout's file descriptor and and then use dup(yoursocket).
Try it and let us know if it works. Also, it would be good if you post some code.
mjguzik
February 12th, 2009, 18:24
Duplicating new descriptor as 1 and then using it with FILE *stdout looks really ugly. (If I misunderstood you, then I'm sorry.) Far better is to use fdopen and freopen later. (Altrough it doesn't seem that this is necessary in this case.)
anemos
February 12th, 2009, 19:14
close(1);
dup(sockfd);
will free file descriptor 1 from stdout and will attach sockfd to it.
Then, the output of, let's say:
printf("Bubbaloo");
will be automatically redirected to the socket.
Until of course the program ends where the file descriptor is being freed up again (this is not definite however).
mjguzik
February 12th, 2009, 19:25
This is dup2() in short. :) bsd_newbie wanted FILE * type so my point is still valid. (And printf() internally uses FILE *stdout too.)
anemos
February 12th, 2009, 19:31
This is dup2() in short. :)
Either dup() or dup2() does the job.
bsd_newbie wanted FILE * type so my point is still valid. (And printf() internally uses FILE *stdout too.)
This is the magic with UNIX. Everything is treated/seen as a file!
Cheers
mjguzik
February 12th, 2009, 19:57
By FILE I mean http://codepad.org/61Jj7Ilw . Just changing the associated descriptor may or may not work correctly, in either case it doesn't look like the right way. freopen() would take care of it I believe.
dap
February 12th, 2009, 20:53
bsd_newbie asked about using fprintf(), so he or she doesn't need to redirect stdout or STDOUT_FILENO.
Personnally I would use this solution:
However, I would take another path and use snprintf() to format string and use regular write() call to send it.
Because this way you still can easily control how many bytes will be sent on the socket.
fonz
February 12th, 2009, 21:34
bsd_newbie asked about using fprintf()
The way I read the OP's question, it pretty much comes down to: "How can I write to a socket instead of stdout?"
That being said, I think the snprintf()/write() idea is indeed the easier, more elegant solution. And possibly more secure too, exactly for the reason you mentioned.
Alphons
SirDice
February 13th, 2009, 12:22
I have some code that is sending output to stdout. I'd like to send it over a socket.
Have a look at the netcat source.
http://www.freebsd.org/cgi/cvsweb.cgi/src/contrib/netcat/
bsd_newbie
February 14th, 2009, 05:59
Thanks for all those who replied. Finally I used this idea with more specific examples from Linux socket programming chap 10 "using standard IO on sockets". fdopen is fine but make sure you use different streams for input and output...
File *rx;
File *tx;
rx = fdopen(s, "r");
if ( !rx ) {
/* Failed */
close(clsd);
continue;
}
tx = fdopen(dup(s), "w");
if (!tx) {
fclose(rx);
continue;
}
setlinebuf(rx);
setlinebuf(tx);
...............
............................
sometime later...
fclose(tx);
shutdown(fileno(rx), SHUT_RDWR);
fclose(rx);
vBulletin® v3.8.7, Copyright ©2000-2013, vBulletin Solutions, Inc.
0