 |
|
 |
|
01-21-05 07:51 AM
Hi,
I have a client - server, but this works only for stdout. What do I have
to change . If I send a 'ls' to the server, I get the correct response
on the client side. If I send a 'ls /sdfdsfdlfsdl' ( a non existing
file), I get the error message on server side on stderr, but on client
side on stdout.
while (FD_ISSET(sockfd, &rfdset))
{
if (select( fd+1 , &rfdset, NULL, NULL, NULL) < 0) {
if (errno != EINTR) {
fprintf(stderr,"select failed\n");
exit(1);
}
}
if (FD_ISSET(sockfd, &rfdset)) {
if ( (numbytes = recv(sockfd, buffer, sizeof(buf), MSG_WAITALL))
< 0 )
{
fprintf(stderr,"recv failed.\n");
exit(1);
}
if ( numbytes ) {
if ( (write(STDOUT_FILENO, buffer, numbytes)) <0) {
fprintf(stderr,"send stdout failed\n");
exit(1);
}
}
else if (numbytes == 0 || errno != EWOULDBLOCK)
FD_CLR(sockfd, &rfdset);
}
}
[ Post a follow-up to this message ]
|
|
|
 |
|
 |
|
 |
 |  |  |  |  |
 |
 |
|
Jens.Toerring@physik.fu-berlin.de |
|
|
 |
 |


 |
 |
 |
|  |  |  |  |
|
01-21-05 12:48 PM
Thomas Beneke <thomas.beneke@web.de> wrote:
> I have a client - server, but this works only for stdout.
What works? What means stdout in the context of a server-client pair?
> What do I have
> to change . If I send a 'ls' to the server, I get the correct response
> on the client side. If I send a 'ls /sdfdsfdlfsdl' ( a non existing
> file), I get the error message on server side on stderr, but on client
> side on stdout.
> while (FD_ISSET(sockfd, &rfdset))
I don't understand what this is good for - using the FD_ISSET macro
only really makes sense *after* you called select().
> {
> if (select( fd+1 , &rfdset, NULL, NULL, NULL) < 0) {
> if (errno != EINTR) {
> fprintf(stderr,"select failed\n");
> exit(1);
> }
> }
> if (FD_ISSET(sockfd, &rfdset)) {
> if ( (numbytes = recv(sockfd, buffer, sizeof(buf), MSG_WAITALL))
> < 0 )
Are you sure the MSG_WAITALL is appropriate here? What is supposd to
happen when the message sent by the server is less than sizeof(buf)
bytes?
> {
> fprintf(stderr,"recv failed.\n");
> exit(1);
> }
> if ( numbytes ) {
> if ( (write(STDOUT_FILENO, buffer, numbytes)) <0) {
> fprintf(stderr,"send stdout failed\n");
> exit(1);
> }
> }
> else if (numbytes == 0 || errno != EWOULDBLOCK)
If recv() didn't return -1 the value of errno doesn't tell you anything,
you are never supposed to do anything with errno's value unless an error
happened. If you feel like checking for EWOULDBLOCK (BTW, it could also
be EAGAIN according to SUSv3) you need to do that further up where you
check 'numbytes' for a negative value.
> FD_CLR(sockfd, &rfdset);
If you call select() with a cleared fdset you tell it to wait for *no*
file descriptors to become ready for reading. I guess you do that because
of the bogus while loop condition at the start. You better make the while
loop an infinite loop (i.e. use "while(1)" and break from it once you find
that you recv() returned 0 (telling you that the other side closed the
socket).
> }
Before you call select() again you must set up the fdset anew - other-
wise the case that select() did return -1 with errno being set to EINTR
won't be dealt with correctly (or if you're dealing with more than a
single file descriptor you call select() on).
> }
If I guess correctly that you want to have your client send a shell
command to the server, have the server execute it by fork()ing and
exec()ing a shell and send back both what the server received from
both the stdout and stderr of the shell it spawned separately, then
you need two logical channels between the server and the client -
one for sending back the result from stdout and one for sending what
appeared on stderr. For that you need either two sockets or you must
develop some kind of protocol that allows the client to figure out
what was what. There's nothing magical about stdout and stderr, they
are just two different file descriptor - and when you have the server
send what it read from both these channels intermixed via a single
channel to the client, the client won't be able to untangle them.
The simplest solution is probably to open two sockets and have the
server write what it got from the stdout of the shell via one of the
sockets and what it read from stderr of the shell to the other one.
The client then listens on both these sockets, writing out what it
receives from the first one to its stdout and what it receives from
the second one to its stderr.
Regards, Jens
PS: I hope you're aware of the security implications of such a server
running on your machine and have access to that server secured by a
password (which you better don't send unencrypted over the net!).
--
\ Jens Thoms Toerring ___ Jens.Toerring@physik.fu-berlin.de
\__________________________ http://www.toerring.de
[ Post a follow-up to this message ]
|
|
|
 |
|
 |
|
 |
 |  |  |  |  |
 |
 |
|
Jens.Toerring@physik.fu-berlin.de |
|
|
 |
 |


 |
 |
 |
|  |  |  |  |
|
01-21-05 10:52 PM
Thomas Beneke <thomas.beneke@web.de> wrote:
> Now I've added on client a second socket()
> errfd = socket(AF_INET, SOCK_STREAM, 0)
> a second connect()
> connect(errfd, (struct sockaddr *)&server, sizeof(struct sockaddr))
> and a FD_ISSET for errfd
> if (FD_ISSET(errfd, &rfdset)) {
> if ( (numbytes = read(errfd, buffer, sizeof(buf))) <= 0 )
> .
> On my server i've added a second getpeername()
> getpeername(err_fd, (struct sockaddr *)&client, &client_len)
No idea what you need that for...
> the pipe(), fork() and exec()
> if (pipe(pipe_out) == -1 || pipe(pipe_err) == -1 )
> exit;
> switch (fork()) {
> case -1:
> fprintf(stderr, "fork failed.\n");
> _exit(1);
> case 0:
> /* child */
> /* stdout. */
> close(pipe_out[0]);
> if (dup2(pipe_out[1], 1) == -1)
It's probably better to write 'STDOUT_FILENO' instead of using the
number 1 here since it's easier to recognnize.
> fprintf(stderr, "aasapd: dup2(pipe_out).\n");
> close(pipe_out[1]);
> /* stderr. */
> close(pipe_err[0]);
> if (dup2(pipe_err[1], 2) == -1)
And here 'STDERR_FILENO'.
> fprintf(stderr, "aasapd: dup2(pipe_err).\n");
> close(pipe_err[1]);
> execl("/bin/sh", "sh", "-c", buffer, (char *) 0);
> _exit(1);
> default:
> default:
> /* parent */
> close(pipe_out[1]);
> close(pipe_err[1]);
> }
> /* only for test */
> numbytes = read(pipe_err[0], buffer, sizeof(buf));
> write(err_fd, buffer, numbytes);
> numbytes = read(pipe_out[0], buffer, sizeof(buf));
> write(client_fd, buffer, numbytes);
> The Problem now is that both outputs using stdin on my client. Why ?
What does that sentence mean? What is "both" and what means "outputs
using stdin"? On the client side what you get from client_fd should
be the stdout of the command the server did run for you and from
err_fd what it got from stderr. If you write that out in your client
you of course have to write what you got from client_fd to the clients
stdout and what you got from err_fd to its stderr file descriptor.
Regards, Jens
--
\ Jens Thoms Toerring ___ Jens.Toerring@physik.fu-berlin.de
\__________________________ http://www.toerring.de
[ Post a follow-up to this message ]
|
|
|
 |
|
 |
|
 |
|
01-21-05 10:52 PM
Jens.Toerring@physik.fu-berlin.de wrote:
> Thomas Beneke <thomas.beneke@web.de> wrote:
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
> No idea what you need that for...
>
>
>
>
>
>
>
>
>
>
>
>
> It's probably better to write 'STDOUT_FILENO' instead of using the
> number 1 here since it's easier to recognnize.
>
>
>
>
>
>
> And here 'STDERR_FILENO'.
>
>
>
>
>
>
>
>
>
>
> What does that sentence mean? What is "both" and what means "outputs
> using stdin"? On the client side what you get from client_fd should
> be the stdout of the command the server did run for you and from
> err_fd what it got from stderr. If you write that out in your client
> you of course have to write what you got from client_fd to the clients
> stdout and what you got from err_fd to its stderr file descriptor.
>
> Regards, Jens
Hi Jens,
if I trace the server I see the normal output is send to 1(STDOUT) and
the error message is send to 2(STDERR). But on the client I get both on
the same fd in my select().
Regards,
Thomas
[ Post a follow-up to this message ]
|
|
|
 |
|
 |
|
 |
 |
|
 |
|
01-21-05 10:52 PM
Jens.Toerring@physik.fu-berlin.de wrote:
> Thomas Beneke <thomas.beneke@web.de> wrote:
>
>
>
> Now you have me completely confused. As far as I understood until now
> you intended to write what the shell did pass via its stdout to the
> server through one socket to the client and what the server got from
> the stderr of the shell would be copied to the other socket. Now you
> suddenly write the server is sending stuff to stdout and stderr and
> there's no mentioning of sockets anymore...
>
>
>
>
> And now we're back to sockets... Do you use different ports for
> the socket you send the stdout stuff to and for the other one
> via which you send the stderr data?
>
> Regards, Jens
Hi Jens,
sorry about the confusion. I use the same ports for both directions.
everthing is fine ('ls /root')
<SNIP>
3927 select(5, [3 4], NULL, NULL, NULL) = 1 (in [3])
3927 read(3,
"Desktop\nblfs.txt\nc_samples\ngew_bereitschaft.txt\ngew_route.sh\nlinux_dis
k.txt\nminicom.log\nplatin.ini\nsapgui.png\nsapmsg.ini\nsaproute.ini\nstarof
fice7\nwebsite\n",
1024) = 154
3927 write(1,
"Desktop\nblfs.txt\nc_samples\ngew_bereitschaft.txt\ngew_route.sh\nlinux_dis
k.txt\nminicom.log\nplatin.ini\nsapgui.png\nsapmsg.ini\nsaproute.ini\nstarof
fice7\nwebsite\n",
154) = 154
3927 select(5, [3 4], NULL, NULL, NULL) = 1 (in [3])
3927 read(3, "", 1024) = 0
3927 close(3) = 0
3927 close(4) = 0
</SNIP>
something wrong ('ls /dfdddfd' #a non existing file)
<SNIP>
3934 select(5, [3 4], NULL, NULL, NULL) = 1 (in [3])
3934 read(3, "ls: ", 1024) = 4
3934 write(1, "ls: ", 4) = 4
3934 select(5, [3 4], NULL, NULL, NULL) = 1 (in [3])
3934 read(3, "", 1024) = 0
3934 close(3) = 0
3934 close(4) = 0
</SNIP>
The output of the second trace reads the client from fd 3 (STDOUT from
server) instead of fd 4 (STDERR from server).
--------------------------------------------------
The trace on the server
for ('ls')
3968 mmap2(NULL, 4096, PROT_READ|PROT_WRITE, MAP_PRIVATE|MAP_ANONYMOUS,
-1, 0) = 0xb7e92000
3968 write(1,
"Desktop\nblfs.txt\nc_samples\ngew_bereitschaft.txt\ngew_route.sh\nlinux_dis
k.txt\nminicom.log\
nplatin.ini\nsapgui.png\nsapmsg.ini\nsaproute.ini\nstaroffice7\nwebsite\n",
154) = 154
3968 close(1) = 0
3968 munmap(0xb7e92000, 4096) = 0
3968 exit_group(0) = ?
3966 <... read resumed> "", 1024) = 0
3966 write(2, "", 0) = 0
3966 read(4,
"Desktop\nblfs.txt\nc_samples\ngew_bereitschaft.txt\ngew_route.sh\nlinux_dis
k.txt\nminicom.log\n
platin.ini\nsapgui.png\nsapmsg.ini\nsaproute.ini\nstaroffice7\nwebsite\n",
1024) = 154
3966 write(0,
"Desktop\nblfs.txt\nc_samples\ngew_bereitschaft.txt\ngew_route.sh\nlinux_dis
k.txt\nminicom.log\
nplatin.ini\nsapgui.png\nsapmsg.ini\nsaproute.ini\nstaroffice7\nwebsite\n",
154) = 154
3966 wait4(-1, NULL, 0, NULL) = 3968
for ('ls /ddddddd')3976 write(2, "ls: ", 4 <unfinished ...>
3974 <... read resumed> "ls: ", 1024) = 4
3974 write(2, "ls: ", 4) = 4
3974 read(4, <unfinished ...>
3976 <... write resumed> ) = 4
3976 write(2, "/ddddddd", 8) = 8
3976 write(2, ": No such file or directory", 27) = 27
3976 write(2, "\n", 1) = 1
3976 exit_group(1) = ?
3974 <... read resumed> "", 1024) = 0
3974 write(0, "", 0) = 0
And here goes something wrong, but I dont no why.
Regards,
Thomas
[ Post a follow-up to this message ]
|
|
|
 |
|
 |
|
 |
 |  |  |  |  |
 |
 |
|
Jens.Toerring@physik.fu-berlin.de |
|
|
 |
 |


 |
 |
 |
|  |  |  |  |
|
01-21-05 10:52 PM
Thomas Beneke <thomas.beneke@web.de> wrote:
> sorry about the confusion. I use the same ports for both directions.
I didn't ask about "directions", I asked if you use two sockets with
_different_ ports for the two channels to the client. If not try that.
> everthing is fine ('ls /root')
> <SNIP>
> 3927 select(5, [3 4], NULL, NULL, NULL) = 1 (in [3])
> 3927 read(3,
> "Desktop\nblfs.txt\nc_samples\ngew_bereitschaft.txt\ngew_route.sh\nlinux_d
isk.txt\nminicom.log\nplatin.ini\nsapgui.png\nsapmsg.ini\nsaproute.ini\nstar
office7\nwebsite\n",
> 1024) = 154
> 3927 write(1,
> "Desktop\nblfs.txt\nc_samples\ngew_bereitschaft.txt\ngew_route.sh\nlinux_d
isk.txt\nminicom.log\nplatin.ini\nsapgui.png\nsapmsg.ini\nsaproute.ini\nstar
office7\nwebsite\n",
> 154) = 154
> 3927 select(5, [3 4], NULL, NULL, NULL) = 1 (in [3])
> 3927 read(3, "", 1024) = 0
> 3927 close(3) = 0
Ok, the data from the successfull call of 'ls' come in via file
desciptor 3.
> 3927 close(4) = 0
> </SNIP>
> something wrong ('ls /dfdddfd' #a non existing file)
> <SNIP>
> 3934 select(5, [3 4], NULL, NULL, NULL) = 1 (in [3])
> 3934 read(3, "ls: ", 1024) = 4
> 3934 write(1, "ls: ", 4) = 4
> 3934 select(5, [3 4], NULL, NULL, NULL) = 1 (in [3])
> 3934 read(3, "", 1024) = 0
> 3934 close(3) = 0
> 3934 close(4) = 0
> </SNIP>
> The output of the second trace reads the client from fd 3 (STDOUT from
> server) instead of fd 4 (STDERR from server).
So there's a problem - probably the other side didn't stuff things into
the appropriate socket.
> The trace on the server
> for ('ls')
> 3968 mmap2(NULL, 4096, PROT_READ|PROT_WRITE, MAP_PRIVATE|MAP_ANONYMOUS,
> -1, 0) = 0xb7e92000
> 3968 write(1,
> "Desktop\nblfs.txt\nc_samples\ngew_bereitschaft.txt\ngew_route.sh\nlinux_d
isk.txt\nminicom.log\
> nplatin.ini\nsapgui.png\nsapmsg.ini\nsaproute.ini\nstaroffice7\nwebsite\n"
,
> 154) = 154
> 3968 close(1) = 0
> 3968 munmap(0xb7e92000, 4096) = 0
> 3968 exit_group(0) = ?
This seems to be the end of ls...
> 3966 <... read resumed> "", 1024) = 0
> 3966 write(2, "", 0) = 0
> 3966 read(4,
> "Desktop\nblfs.txt\nc_samples\ngew_bereitschaft.txt\ngew_route.sh\nlinux_d
isk.txt\nminicom.log\n
> platin.ini\nsapgui.png\nsapmsg.ini\nsaproute.ini\nstaroffice7\nwebsite\n",
> 1024) = 154
> 3966 write(0,
> "Desktop\nblfs.txt\nc_samples\ngew_bereitschaft.txt\ngew_route.sh\nlinux_d
isk.txt\nminicom.log\
> nplatin.ini\nsapgui.png\nsapmsg.ini\nsaproute.ini\nstaroffice7\nwebsite\n"
,
> 154) = 154
> 3966 wait4(-1, NULL, 0, NULL) = 3968
You keep me guessing: is 0 the file descriptor for one of the sockets?
Without knowing what the file descriptors stand for I can hardly gues
what might go wrong. Why not post the source code instead of heavily
snipped strace output?
> for ('ls /ddddddd')3976 write(2, "ls: ", 4 <unfinished ...>
> 3974 <... read resumed> "ls: ", 1024) = 4
> 3974 write(2, "ls: ", 4) = 4
> 3974 read(4, <unfinished ...>
> 3976 <... write resumed> ) = 4
> 3976 write(2, "/ddddddd", 8) = 8
> 3976 write(2, ": No such file or directory", 27) = 27
> 3976 write(2, "\n", 1) = 1
> 3976 exit_group(1) = ?
Looks like ls is done...
> 3974 <... read resumed> "", 1024) = 0
> 3974 write(0, "", 0) = 0
Where is the part were you write to the socket? I just see a single write
of 0 bytes to 0 (all the rest seems more like something coming from 'ls'),
not even something getting actually read from the output of ls.
Just a question: did you switch from the fork/dup2/execl to using popen()?
In that case all this wouldn't be astonishing since with popen() you can't
get stdout and stderr separately...
Regards, Jens
--
\ Jens Thoms Toerring ___ Jens.Toerring@physik.fu-berlin.de
\__________________________ http://www.toerring.de
[ Post a follow-up to this message ]
|
|
|
 |
|
 |
|
 |
|
01-22-05 07:48 AM
In article <35cu4hF4kv73tU1@uni-berlin.de>,
Jens.Toerring@physik.fu-berlin.de wrote:
> Just a question: did you switch from the fork/dup2/execl to using popen()?
> In that case all this wouldn't be astonishing since with popen() you can't
> get stdout and stderr separately...
Actually, when you use popen() you can't get stderr at all, it only
redirects stdout. You can only get stdout if the command line includes
2>&1, which explicitly merges stderr with stdout.
--
Barry Margolin, barmar@alum.mit.edu
Arlington, MA
*** PLEASE post questions in newsgroups, not directly to me ***
[ Post a follow-up to this message ]
|
|
|
 |
|
 |
|
 |
|
01-24-05 12:47 PM
Jens.Toerring@physik.fu-berlin.de wrote:
> Thomas Beneke <thomas.beneke@web.de> wrote:
>
>
>
> I didn't ask about "directions", I asked if you use two sockets with
> _different_ ports for the two channels to the client. If not try that.
>
>
>
>
> Ok, the data from the successfull call of 'ls' come in via file
> desciptor 3.
>
>
>
>
>
>
>
>
> So there's a problem - probably the other side didn't stuff things into
> the appropriate socket.
>
>
>
>
>
>
> This seems to be the end of ls...
>
>
>
>
> You keep me guessing: is 0 the file descriptor for one of the sockets?
> Without knowing what the file descriptors stand for I can hardly gues
> what might go wrong. Why not post the source code instead of heavily
> snipped strace output?
>
>
>
>
> Looks like ls is done...
>
>
>
>
> Where is the part were you write to the socket? I just see a single write
> of 0 bytes to 0 (all the rest seems more like something coming from 'ls'),
> not even something getting actually read from the output of ls.
>
> Just a question: did you switch from the fork/dup2/execl to using popen()?
> In that case all this wouldn't be astonishing since with popen() you can't
> get stdout and stderr separately...
>
> Regards, Jens
Hi Jens,
I didn't switch to using popen(). Over the weekend I tried to find a
solution for my problem but I didn't find.
Regards,
Thomas
[ Post a follow-up to this message ]
|
|
|
 |
|
 |
|
 |
|
|
|
Sponsored Links |
 |
 |
|
|
 |
All times are GMT. The time now is 08:25 PM. |
 |
|
|
 |
|
 |
|
|
 |
|
Forum Rules:
You may not post new threads
You may not post replies
You may not post attachments
You may not edit your posts
|
HTML code is OFF
vB code is ON
Smilies are ON
[IMG] code is OFF
|
|
|
|
Medical and Health forum | Computer Games Reviews | Graphics design forum
|
 |
|
 |
|