Link to home
Start Free TrialLog in
Avatar of F-J-K
F-J-KFlag for Canada

asked on

Very Basic Tcp Client-Server C++ Code. Weird Output! Easy Question - Help!

I wrote my first client-server in C/C++ under linux by using g++ compiler. My algorithm is fine, the program works, but there is something weird happens at the beginning of output.

Program description: server binds to a port you specify, then keep listening...
client ask for IP & port you want to connect to. Once connected, you send a text
message to the server. Server echos back the same message to you....

Server Interface:

fahmi@Toshiba-Laptop:~/Desktop$ ./a.out
Choose a port to listen on: 2000
waiting for a connection ...
New Client connected from port no 35302 and IP ::aff:40fe:87bf
Sent mesg:
Sent mesg: 1
Sent mesg: Hello There!
Client disconnected

New Client connected from port no 35303 and IP ::ffff:127.0.1.1
************Sent mesg:**************why does this line appear?
Sent mesg: Test Again!
Sent mesg: HEy
Sent mesg: works...
Sent mesg: am out
Client disconnected


Clients Interface:

Enter Server IP: 127.0.1.1
Enter a Port Number: 2000
connecting ...
connection succeeded
***************you: server:*****************why does line appear?

you: Test Again!
server: Test Again!

you: HEy
server: HEy

you: works...
server: works...

you: am out
server: am out

you:
fahmi@Toshiba-Laptop:~/Desktop$

-------------------------------------------------------------------------

Regarding my code structure, i do not see any mean for the places i put asterisks  to appear!!!

It does not effect my code, but its good to know why this happens!

I hope my question is clear....

//**********piece of the server source code:************
.
.
.
.
//listens forever, and accepts all connections that come in
while(1)
{
//accept pending connection. Information of incoming connection will go to clientInfo
clientSockD = accept(serverSockD, &clientInfo, &clientInfo_size);
 
if(clientSockD == ERROR)
{
perror("accept");
return 5;
}
 
clientIP = get_client_addr(&clientInfo);
 
portNum = get_client_port(&clientInfo);
 
inet_ntop(clientInfo.sa_family, clientIP, printableClientIP, sizeof printableClientIP);
 
//convert the port number from network byte order to host byte order
long portHostByte = ntohs(portNum);
 
//print to screen the current clients' IP Address & the port the client's is connected from
printf("New Client connected from port no %d and IP %s\n", portHostByte, printableClientIP);
 
bytes_received = 1;
 
while(bytes_received)
{
bytes_received = recv(clientSockD, data, MAX_DATA, 0);
 
//bytes_received larger than 0, send back to client what client's sent you
if(bytes_received)
{
send(clientSockD, data, bytes_received, 0);
data[bytes_received] = '\0';
printf("Sent mesg: %s", data);
}
 
}
 
printf("Client disconnected\n");
.
.
.
 
//*********************************************************************
 
//**********Piece of the client source code**********************
 
.
.
.
 
while(1)
{
//stores input from screen
cout<<"you: ";
fgets(clientInput, MAX_DATA, stdin);
 
//send input to connected server
send(sockfd, clientInput, strlen(clientInput), 0);
 
int bytes_received = recv(sockfd, serverResponse, MAX_DATA, 0);
 
cout<<"server: ";
serverResponse[bytes_received] = '\0';
printf("%s\n", serverResponse);
}
 
//close the socket
close(sockfd);
.
.
.
.

Open in new window

Avatar of woolmilkporc
woolmilkporc
Flag of Germany image

Hi,
  did you clear your 'data' and 'ServerResponse' arrays before recv(),
 e.g. bzero(data,123); ?
 wmp
Avatar of F-J-K

ASKER

I have no idea what that is... :-/, i will google it.
Note: this appears at the very beginning of executing the program only, when recv() has not yet received anything! The client connection just got accepted with no previous background or activities.....
SOLUTION
Avatar of Infinity08
Infinity08
Flag of Belgium image

Link to home
membership
This solution is only available to members.
To access this solution, you must be a member of Experts Exchange.
Start Free Trial
Avatar of F-J-K

ASKER

ha right! how come i forgot it!....i'll check it out
Avatar of drichards
drichards

I woudl look on the client side for the problem because the server is just responding to the data sent by the client, and the client output shows that you send a blank something right at the start.  Does that appear right away when you start the program, or does it not appear until you type something and the first data causes two outputs?

If you debug the client and see what is returned from fgets on the first iteration, you shoudl be able to tell what is going on.
Avatar of F-J-K

ASKER

>>recv can return -1 in case of error. Check for that value before continuing (look at errno to know what the error was).

No errors returned.


>>Does that appear right away when you start the program, or does it not appear until you type something and the first data causes two outputs? If you debug the client and see what is returned from fgets on the first iteration, you shoudl be able to tell what is going on.

Appear right away when you start the program...

hm, i can say everytime program starts, client gets like an empty character or something like that (special weird unseen character) automatically & send it to server, then server replies. Thats why. Now, why this happens :-)...Does fgets() takes a "\0" from the previous input? I have not had fgets() in the code somewhere else....

It works fine when i do cin>>clientInput; instead of fgets(clientInput, MAX_DATA, stdin);
but cin>> only takes one word at a time only :-/. I wanted fget() so i can get whole sentences.



Avatar of F-J-K

ASKER

Another question:

Bytes sent & received always increased by one.

If i send "hello" from client. Server bytes_received carries 6
client bytes_received carries 6 too.... It should be five....

Any idea?
   
2. bytes_received = recv(clientSockD, data, MAX_DATA, 0);
 if(bytes_received)
{
                                cout<<"Bytes Sent to Client: "<<bytes_received<<endl;
                        send(clientSockD, data, bytes_received, 0);
                        data[bytes_received] = '\0';
                        printf("Sent mesg: %s", data);
                        cout<<"Bytes Sent to Client: "<<bytes_received<<endl;
}

Eventhough, i did it right. I still do not know how '\0' fit into data[bytes_received]...
I know when data is received from clientSocketD, and stored into data[MAX_DATA]. '\0' is dropped. We put '\0' to the array, so it could be printed by using prinf(). My questios is:
bytes_received should get 5 when it receives  "hello" & bytes_received should get 6 when it receives hello\0 ... but as you see, we add null at the end of the array before we print it, so the output of the above code should be as follows:

Bytes Sent to Client: 5
Sent mesg: hello
Bytes Sent to Client: 6

But the output appears on screen is

Bytes Sent to Client: 6
Sent mesg: hello
Bytes Sent to Client: 6

What i think is: array is fixed, when a client send hello - it reaches to server as hello\0 .... 6 bytes
but NULL is dropped, so there is one empty space at the last spot that need to be filled with NULL before pass data to printf() ..... Is this right?

3. why don't we add a parameter in send() that carries '\0' as we know when recv() returned the value, null was dropped. In our case, if we use send(), data will be sent but without NULL, because when received the data, null is dropped. Can you explain it to me please!

My question are long just to make it clear & try to get readers to understand what i'm trying to ask exactly......Thanks for being patience...
Avatar of F-J-K

ASKER

Regarding the weird output

you: server:

i solved it....

I just put cin.ignore(); before while(1), because as you know cin leaves \0 hanged. Thus, when a function such as getline() get implemented, it will take the last remained character in cin, which is \0. Therefore, i did not get a chance to enter anything at the first time, as the client fgets() grabbed the \0 that is hanged around after i used cin>>remotePort, so i have to use cin.ignore() to let fgets() taking anything from the last standard input. I thought only getline() does this....Anyway, it worked and i hope the concept is right.

I will be glad if i could an answer to above posted questions regarding the number of bytes.
ASKER CERTIFIED SOLUTION
Link to home
membership
This solution is only available to members.
To access this solution, you must be a member of Experts Exchange.
Start Free Trial
Avatar of F-J-K

ASKER

THANKS