 |
|
 |
|
|
 |
Socket programming problem: can't generate output in server socket |
 |
 |
|
|
06-21-05 07:50 AM
Hello all,
This may sound pretty basic stuff.. but I'm working on a socket example
in which the client seems to work fine, but the server doesn't send to
the client the expected result. The problem is that I want to trace what
the server socket is doing, but I'm unable to see any of my fprintf or
printf stuff.
Please take a look at the example:
#include <stdlib.h>
#include <netinet/in.h>
#include <sys/socket.h>
#include <sys/types.h>
#include <string.h>
#include <stdio.h>
#include <unistd.h>
//x ------------------------------------------------------------ x
#define MAXLINE 4096 /* max text line length */
int main(int argc, char **argv)
{
int listenfd, connfd; // socket file descriptor
struct sockaddr_in servaddr; // IPv4 socket address structure
char buff[MAXLINE];
// ********************
char file[32];
FILE *fp;
strcpy(file,"output.txt");
if ((fp = fopen(file, "w")) == NULL)
{
printf("Can't open %s\n", file);
exit(1);
}
else
fprintf(fp, "\nFirst step...");
// ********************
listenfd = socket(AF_INET, SOCK_STREAM, 0); // call to socket function
bzero(&servaddr, sizeof(servaddr)); // initialization of socket
structure to 0
servaddr.sin_family = AF_INET;
servaddr.sin_port = htons(9877); // Port in host byte order must be
converted
// to network byte order
servaddr.sin_addr.s_addr = htonl(INADDR_ANY);
// INADDR_ANY - wild card
// This tells the kernel to choose the IP address
bind(listenfd, (struct sockaddr *)&servaddr, sizeof(servaddr));
fprintf(fp, "\nWaiting for connection, BEFORE call to listen()");
listen(listenfd, 5);
fprintf(fp, "\nWaiting for connection, AFTER call to listen()");
for ( ; ; ) {
if (connfd = accept (listenfd, NULL, NULL) < 0)
fprintf(fp, "\nERROR on accept");
else
fprintf(fp, "\nSUCCESS on accept");
// We are not interested in knowing the identity of the client
// Therefore, 2nd and 3rd param. to NULL
strcpy(buff, "Output to the client");
snprintf(buff, sizeof(buff), "%%" );
write(connfd, buff, strlen(buff));
close(connfd);
}
// exit(0);
// ********************
fclose(fp);
// ********************
}
As you can see, there are many fprintf instructions which work fine in
my socket client but not in the server. I guess I'm missing some
conceptual stuff here. Any idea?
Thanks!
Fernando
[ Post a follow-up to this message ]
|
|
|
 |
|
 |
|
 |
|
|
 |
Re: Socket programming problem: can't generate output in server socket |
 |
 |
|
|
06-21-05 07:50 AM
On Tue, 21 Jun 2005 08:08:32 +0400, Fernando Barsoba
<fbarsoba@verizon.net> wrote:
> Hello all,
>
> This may sound pretty basic stuff.. but I'm working on a socket example
> in which the client seems to work fine, but the server doesn't send to
> the client the expected result. The problem is that I want to trace what
> the server socket is doing, but I'm unable to see any of my fprintf or
> printf stuff.
Did you consider using tcpdump ?
[]
> for ( ; ; ) {
>
> if (connfd = accept (listenfd, NULL, NULL) < 0)
> fprintf(fp, "\nERROR on accept");
> else
> fprintf(fp, "\nSUCCESS on accept");
> // We are not interested in knowing the identity of the client
> // Therefore, 2nd and 3rd param. to NULL
> strcpy(buff, "Output to the client");
> snprintf(buff, sizeof(buff), "%%" );
> write(connfd, buff, strlen(buff));
> close(connfd);
> }
[]
You do odd things with buff. First you copy "Output to the client" into
buff, then you overwrite it with a % and a zero characters. In the end you
end up sending a client just those two characters. Is that what you want?
--
Maxim Yegorushkin
<firstname.lastname@gmail.com>
[ Post a follow-up to this message ]
|
|
|
 |
|
 |
|
 |
|
|
 |
Re: Socket programming problem: can't generate output in server socket |
 |
 |
|
|
06-21-05 07:50 AM
It seems surprising , because you will start the server first, it
should atleast print the fprintf("First step...") atleast in your file.
Does it atleast do that?
The other thing which I feel is if you have put the client in an
endless loop and is doing a fprintf there then it fills in the entire
file, what it does it writes into that file only the client fprintf.
Could you also post the client code?
You should have some
[ Post a follow-up to this message ]
|
|
|
 |
|
 |
|
 |
|
|
 |
Re: Socket programming problem: can't generate output in server socket |
 |
 |
|
|
06-21-05 10:53 PM
Maxim Yegorushkin wrote:
> On Tue, 21 Jun 2005 08:08:32 +0400, Fernando Barsoba
> <fbarsoba@verizon.net> wrote:
>
>
>
> Did you consider using tcpdump ?
>
I'm going to try to use tcpdump... thanks.
> []
>
>
>
> []
>
> You do odd things with buff. First you copy "Output to the client" into
> buff, then you overwrite it with a % and a zero characters. In the end
> you end up sending a client just those two characters. Is that what you
> want?
>
No, that's not what I want. But it would be ok with me if the server did
that. I'm not very good at C, and I'm just starting at network
programming through an example from the Richard Steven's book.
What about if I commented out the snprintf sentence? I would like the
whole "Output to the client" string to be printed out on the client console.
// snprintf(buff, sizeof(buff), "%%" );
Thanks,
Fernando
[ Post a follow-up to this message ]
|
|
|
 |
|
 |
|
 |
|
|
 |
Re: Socket programming problem: can't generate output in server socket |
 |
 |
|
|
06-21-05 10:53 PM
Rajan wrote:
> It seems surprising , because you will start the server first, it
> should atleast print the fprintf("First step...") atleast in your file.
> Does it atleast do that?
No, its' very strange.. it doesnt' even print that.
> The other thing which I feel is if you have put the client in an
> endless loop and is doing a fprintf there then it fills in the entire
> file, what it does it writes into that file only the client fprintf.
> Could you also post the client code?
> You should have some
>
You're right.. let me show the client.. When I execute it, the
connection is established.
Output:
x--------------x
Connecting to socket...
Connection established!
x--------------x
#include <stdlib.h>
#include <arpa/inet.h>
#include <string.h>
#include <stdio.h>
#include <netinet/in.h>
#include <sys/socket.h>
int inet_pton(int, const char *, void *);
int inet_aton(const char *, struct in_addr *);
/* include inet_pton */
int inet_pton(int family, const char *strptr, void *addrptr)
{
if (family == AF_INET) {
struct in_addr in_val;
if (inet_aton(strptr, &in_val)) {
memcpy(addrptr, &in_val, sizeof(struct in_addr));
return (1);
}
return(0);
}
//errno = EAFNOSUPPORT;
return (-1);
}
int main(int argc, char **argv)
{
int sockfd; // socket file descriptor
struct sockaddr_in servaddr; // IPv4 socket address structure
//sockfd = socket(AF_INET, SOCK_STREAM, 0); // call to socket function
printf("Connecting to socket...");
if ( (sockfd = socket(AF_INET, SOCK_STREAM, 0)) < 0)
printf("Socket Error");
bzero((char *) &servaddr, sizeof(servaddr)); // initialization of
socket structure to 0
servaddr.sin_family = AF_INET;
servaddr.sin_port = htons(9877); // Port in host byte order must be
converted
// to network byte order
if (inet_pton(AF_INET, argv[1], &servaddr.sin_addr) <= 0)
printf("\ninet_pton error");
if (connect(sockfd,( struct sockaddr *) &servaddr, sizeof(servaddr)) < 0)
printf("\nError connecting to server!");
// Connection to port 9877, IP?
else
printf("\n\nConnection established!");
exit(0);
}
---------------
Thanks!
Fernando
[ Post a follow-up to this message ]
|
|
|
 |
|
 |
|
 |
|
|
 |
Re: Socket programming problem: can't generate output in server socket |
 |
 |
|
|
06-22-05 07:50 AM
On Tue, 21 Jun 2005 19:30:41 +0400, Fernando Barsoba
<fbarsoba@verizon.net> wrote:
[]
> No, that's not what I want. But it would be ok with me if the server did
> that. I'm not very good at C, and I'm just starting at network
> programming through an example from the Richard Steven's book.
>
> What about if I commented out the snprintf sentence? I would like the
> whole "Output to the client" string to be printed out on the client
> console.
> // snprintf(buff, sizeof(buff), "%%" );
>
I've just stripped down your example and compiled it:
int main(int argc, char **argv)
{
int listenfd, connfd;
struct sockaddr_in servaddr;
listenfd = socket(AF_INET, SOCK_STREAM, 0);
memset(&servaddr, 0, sizeof(servaddr));
servaddr.sin_family = AF_INET;
servaddr.sin_port = htons(9877);
servaddr.sin_addr.s_addr = htonl(INADDR_ANY);
bind(listenfd, (struct sockaddr *)&servaddr, sizeof(servaddr));
listen(listenfd, 5);
for ( ; ; ) {
connfd = accept (listenfd, NULL, NULL);
write(connfd, "Output to the client\n", sizeof("Output to the
client\n") - 1);
close(connfd);
}
}
Run it and it seems to work fine:
[max@my ~]$ telnet localhost 9877
Trying 127.0.0.1...
Connected to localhost.localdomain (127.0.0.1).
Escape character is '^]'.
Output to the client
Connection closed by foreign host.
--
Maxim Yegorushkin
[ Post a follow-up to this message ]
|
|
|
 |
|
 |
|
 |
|
|
 |
Re: Socket programming problem: can't generate output in server socket |
 |
 |
|
|
06-22-05 07:50 AM
I am curious to know , what was the objective in writing such a client,
wherein you are not sending any data to the server?
It would be good if you do write(sockfd,buff,sizeof(buff)) in your
client program sends the data to the server, which in turn in the
server program you must do a read(connfd, buff,sizeof(buff)) and then
do a
write(1,buff,sizeof(buff)).
I would like to take Maxim's example and add some more things to it to
help you understand a simple client-server example.
I am also incorporating some changes in the client code that you have
written.
I think a simple client-server example does not need inet_aton,
inet_pton to be used, but I won't discourage you from using them, it's
your choice.
int main(int argc, char **argv)
{
int listenfd, connfd;
struct sockaddr_in servaddr;
char buff[1024]; /* Added by Rajan */
listenfd = socket(AF_INET, SOCK_STREAM, 0);
memset(&servaddr, 0, sizeof(servaddr));
servaddr.sin_family = AF_INET;
servaddr.sin_port = htons(9877);
servaddr.sin_addr.s_addr = htonl(INADDR_ANY);
bind(listenfd, (struct sockaddr *)&servaddr, sizeof(servaddr));
listen(listenfd, 5);
for ( ; ; ) {
connfd = accept (listenfd, NULL, NULL);
/************* Added by Rajan **************************/
memset(buff,'\0',sizeof(buff));
read(connfd,buff,sizeof(buff));/* This will read data from the
socket and put it into the buff */
write(1,buff,strlen(buff));/* This will print the data sent
from the client to the stdout */
/ ****************************************
***********************************
/
write(connfd, "Output to the client\n", sizeof("Output to the
client\n") - 1);
close(connfd);
}
}
Your client code may have following changes
int main(int argc, char **argv)
{
int sockfd; // socket file descriptor
struct sockaddr_in servaddr; // IPv4 socket address
structure
char buff[1024];/* Added by Rajan */
//sockfd = socket(AF_INET, SOCK_STREAM, 0); // call to
socket function
printf("Connecting to socket...");
if ( (sockfd = socket(AF_INET, SOCK_STREAM, 0)) < 0)
printf("Socket Error");
bzero((char *) &
servaddr, sizeof(servaddr)); // initialization of
socket structure to 0
servaddr.sin_family = AF_INET;
servaddr.sin_port = htons(9877); // Port in host byte
order must be
converted
// to network byte order
if (inet_pton(AF_INET, argv[1], &servaddr.sin_addr) <= 0)
printf("\ninet_pton error");
if (connect(sockfd,( struct sockaddr *) &servaddr,
sizeof(servaddr)) < 0)
printf("\nError connecting to server!");
// Connection to port 9877, IP?
else
{
printf("\n\nConnection established!");
/********************** Added by Rajan
***************************/
memset(buff,'\0',1024);
strcpy(buff,"Connection established");
write(sockfd,buff,sizeof(buff)); /* this will send the data
from the client to the server */
memset(buff,'\0',1024);/* The buff is again set to 0 so that
you refresh it.
read(sockfd,buff, sizeof(buff));/* This will read the data
"Output sent to the client" from the server socket to the buffer
write(1,buff,strlen(buff)); /* This will print the data
"Output sent to the client on the stdout
/ ****************************************
*******************************/
}
exit(0);
}
[ Post a follow-up to this message ]
|
|
|
 |
|
 |
|
 |
|
|
 |
Re: Socket programming problem: can't generate output in server socket |
 |
 |
|
|
06-22-05 12:54 PM
I think in the client example add a char buff[1024] or of any size.
Then instead of writing on the stdout by using printf for "Connection
established" you can use a write(sockfd,buff,strlen(buff)) which sends
the data over the socket to the server.
Then in the client code you need to read(sockfd,buff,sizeof(buff));
and write(1,buff,strlen(buff)); which would print "Output to the
client" on the stdout.
In the server code of Maxim's I would like to add some more thing like
connfd = accept (listenfd, NULL, NULL);
/* Added by Rajan */
read(connfd,buff,sizeof(buff));
write(1,buff,strlen(buff)); /* This will print "Connection established"
on stdout .*/
write(connfd, "Output to the client\n", sizeof("Output to the
client\n") - 1);
close(connfd);
[ Post a follow-up to this message ]
|
|
|
 |
|
 |
|
 |
|
|
 |
Re: Socket programming problem: can't generate output in server socket |
 |
 |
|
|
06-22-05 12:54 PM
"Rajan" <rstalekar@yahoo.com> wrote in message
news:1119430053.111503.171310@g44g2000cwa.googlegroups.com...
>I think in the client example add a char buff[1024] or of any size.
> Then instead of writing on the stdout by using printf for "Connection
> established" you can use a write(sockfd,buff,strlen(buff)) which sends
> the data over the socket to the server.
> Then in the client code you need to read(sockfd,buff,sizeof(buff));
> and write(1,buff,strlen(buff)); which would print "Output to the
> client" on the stdout.
> In the server code of Maxim's I would like to add some more thing like
> connfd = accept (listenfd, NULL, NULL);
> /* Added by Rajan */
> read(connfd,buff,sizeof(buff));
> write(1,buff,strlen(buff)); /* This will print "Connection established"
> on stdout .*/
> write(connfd, "Output to the client\n", sizeof("Output to the
>
> client\n") - 1);
> close(connfd);
That's just plain horrible style, requiring you to overwrite the buffer
with zeroes before each read or the following happens:
1) Your buffer is all zeroes.
2) You receive "foo bar baz".
3) You send "foo bar baz".
4) You loop to do it again, and receive "qux".
5) You now have "qux bar baz" in your buffer.
6) You send "qux bar baz" even though you have received it.
And you can't fix this by sending the terminating zero either. (If you
don't know why, you have no business writing TCP code!)
Much more logical is:
i=read(connfd, buff, sizeof(buff)-1);
if(i<=0)
{
/* EOF or error */
}
else
{
buf[i]=0; /* if and only if you need it zero-terminated */
write(1, buff, i);
}
You only need the 'buf[i]=0;' if you really need to do 'strlen' or some
other string function on the received data. Otherwise, there is no need to
put a zero byte at the end of it.
DS
[ Post a follow-up to this message ]
|
|
|
 |
|
 |
|
 |
|
|
 |
Re: Socket programming problem: can't generate output in server socket |
 |
 |
|
|
06-22-05 10:57 PM
Maxim Yegorushkin wrote:
> On Wed, 22 Jun 2005 11:32:08 +0400, Rajan <rstalekar@yahoo.com> wrote:
>
> []
>
>
>
> Please note, that the code suffers from a common error.
>
> You buff is declared as char buff[1024]. TCP MSS (maximum segment size
)
> is often more than 1024 bytes., what means a read can fill the whole
> buff without the null terminator, so guess what happens when you call
> strlen() on the buff.
>
That's absolutely true. It's a limitation of TCP. You have buff of 4096
and then you have to keep reading from buff until emptying it..
From Steven's book:
"Stream sockets (e.g., TCP sockets) exhibit a behavior with the read and
write functions that differs from normal file I/O. A read or write on a
stream socket might input or output fewer bytes than requested, but this
is not an error condition. The reason is that buffer limits might be
reached for the socket in the kernel. All that is required to input or
output the remaining bytes is for the caller to invoke the read or write
function again. Some versions of Unix also exhibit this behavior when
writing more than 4,096 bytes to a pipe. This scenario is always a
possibility on a stream socket with read, but is normally seen with
write only if the socket is nonblocking. "
> The correct code looks like:
>
> // no need to zero out the buff
> ssize_t n = read(connfd, buff, sizeof(buff));
> if(n > 0)
> write(..., buff, n); // no need for strlen
> else if(0 == n)
> // handle EOF
> else
> // handle error
>
[ Post a follow-up to this message ]
|
|
|
 |
|
 |
|
 |
|
|
|
Sponsored Links |
 |
 |
|
|
 |
All times are GMT. The time now is 10:01 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
|
 |
|
 |
|