fprintf on a socket

bsd_newbie

Member


Messages: 36

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

Well-Known Member

Reaction score: 67
Messages: 392

I would expect so - if it looks like a file, you should be able to treat it as one.

Try?
 

dh

Member

Reaction score: 21
Messages: 93

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:
Code:
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

Member

Reaction score: 21
Messages: 93

Oh nevermind, I didn't read orignal post carefully enough... you already mentioned fdopen().
 

anemos

Member

Reaction score: 16
Messages: 58

You can do
Code:
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

Member

Reaction score: 7
Messages: 36

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

Member

Reaction score: 16
Messages: 58

Code:
close(1);
dup(sockfd);
will free file descriptor 1 from stdout and will attach sockfd to it.
Then, the output of, let's say:
Code:
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

Member

Reaction score: 7
Messages: 36

This is dup2() in short. :) bsd_newbie wanted FILE * type so my point is still valid. (And printf() internally uses FILE *stdout too.)
 

anemos

Member

Reaction score: 16
Messages: 58

mjguzik said:
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
 

dap

Member

Reaction score: 2
Messages: 20

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:
dh said:
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

Son of Beastie

Reaction score: 369
Messages: 2,560

dap said:
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
 
OP
OP
B

bsd_newbie

Member


Messages: 36

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);
 
Top