Server and Client are not working as it was intented too.
Can anyone tell me why my server and client are noting working as it was intented too?
Anyway here are my questions:
1. How come my client does not receive the welcome message once it has established a
connection with the server?
2. What is the problem that is causing my client not to send the whole string as it was
specified by the user. For example the string "Hello, Server!" without the quotation
marks get send as two different packets instead of one. Look at "Output for client"
no quotation marks.
3. Why does the server just hangs around after the client sends a packet to the server
and doesn't send anything back to the client as it was intended according to the
code?
Look at "Output for server" no quotation marks.
Relevant information
Code:
OS: Linux
Compiler: GCC
Code:
/***************************************************************************
* Copyright (C) 2007 by Cloud *
* cloud@laptop *
* *
* This program is free software; you can redistribute it and/or modify *
* it under the terms of the GNU General Public License as published by *
* the Free Software Foundation; either version 2 of the License, or *
* (at your option) any later version. *
* *
* This program is distributed in the hope that it will be useful, *
* but WITHOUT ANY WARRANTY; without even the implied warranty of *
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the *
* GNU General Public License for more details. *
* *
* You should have received a copy of the GNU General Public License *
* along with this program; if not, write to the *
* Free Software Foundation, Inc., *
* 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA. *
***************************************************************************/
#ifdef HAVE_CONFIG_H
#include <config.h>
#endif
#include <stdio.h>
#include <stdlib.h>
#include <sys/types.h>
#include <sys/socket.h>
#include <netinet/in.h>
#include <string.h>
#include <arpa/inet.h>
#include <strings.h>
#define MAX_BUFFER_SIZE 1024
#define MAX_CONNECTIONS 5
/**
* Function declarations
*/
void error (char *);
void makeServerSocket (char *[]);
void makeClientSocket (char *[]);
/**
*
*/
int main(int argc, char *argv[]) {
int socketType=0;
argv[0]="127.0.0.1";
argv[1]="10000";
printf("Socket v0.01\n\n");
/*if (argc<3) {
printf("Usage: IP Address (xxx.xxx.xxx.xxx) Port Number (xxxxx)");
exit(1);
}*/
printf("Select socket type (0=client, 1=Server)\n");
scanf("%d", &socketType);
if (socketType) {
printf("Server type socket selected.\n\n");
makeServerSocket(argv);
} else {
printf("Client type socket selected.\n\n");
makeClientSocket(argv);
}
return EXIT_SUCCESS;
}
/**
*
*/
void error(char *message) {
perror(message);
exit(1);
}
/**
*
*/
void makeServerSocket(char *argv[]) {
int serverSocketFD=0;
int clientSocketFD;
char buffer[MAX_BUFFER_SIZE];
int bytesReceived=0;
struct sockaddr_in client;
struct sockaddr_in server;
int length=sizeof (client);
int reuseAddr=1;
// create server socket
if ((serverSocketFD=socket(PF_INET, SOCK_STREAM, 0))<1) error("Can not create server socket.\n");
// set up socket connection
bzero(&server, sizeof(server));
server.sin_family=PF_INET;
server.sin_addr.s_addr=INADDR_ANY;
server.sin_port=htons((unsigned int) atoi(argv[1]));
// bind the socket to a port
if (bind(serverSocketFD, (struct sockaddr*) &server, sizeof(server))!=0) {
error("Can not bind socket to port.\n");
// reuse the same port
/*if (setsockopt(*serverSocketFD, SOL_SOCKET, SO_REUSEADDR, &reuseAddr, sizeof(int))==-1)
error("Cannot bind socket to port and cannot reuse port.\n"); */
}
// Zero out the client structure
bzero(&client, sizeof(client));
// make the socket listen
if (listen(serverSocketFD, MAX_CONNECTIONS)!=0) error("Can not make socket listen to incoming messages.\n");
while (1) {
// make the server accecpt incoming messages
if ((clientSocketFD=accept(serverSocketFD, (struct sockaddr*) &client, &length))==-1) {
close(serverSocketFD);
close(clientSocketFD);
error("Server cannot accept incoming message.");
} else {
printf("Client %s:%d connected.\n\n", inet_ntoa(client.sin_addr), ntohs(client.sin_port));
send(clientSocketFD, "Welcome Client! I'm a server.\n\n", 31, 0);
}
if ((bytesReceived=recv(clientSocketFD, buffer, MAX_BUFFER_SIZE, 0))<1) {
close(clientSocketFD);
close(serverSocketFD);
error("No data received.");
} else if (strncasecmp(buffer, "quit", 4)==0) {
printf("\"Quit\" command received.\nShutting server!\n");
close(clientSocketFD);
close(serverSocketFD);
exit(EXIT_SUCCESS);
} else if (bytesReceived>0) {
printf("Message (%d byte(s)) received from the client(%s:%d):\n%s\n",bytesReceived, inet_ntoa(client.sin_addr), ntohs(client.sin_port), buffer);
// send back anything that was send
if (send(clientSocketFD, buffer, bytesReceived, 0)==-1) error("Error send data.\n");
}
bzero(buffer, sizeof(buffer));
}
}
/**
*
*/
void makeClientSocket(char *argv[]) {
int clientSocketFD;
char buffer[MAX_BUFFER_SIZE]="";
int bytesRead=0;
struct sockaddr_in server;
// create client socket
bzero(&server, sizeof(server));
if ((clientSocketFD=socket(PF_INET, SOCK_STREAM, 0))<1) error("Can not create client socket");
// set up server connection
server.sin_family=PF_INET;
server.sin_port=htons((unsigned int) atoi(argv[1]));
if (inet_aton(argv[0], &(server.sin_addr))==0) error("Server IP address error.\n");
// connect the client to the server
if (connect(clientSocketFD, (struct sockaddr*) &(server), sizeof(server))==-1) error("Can not connect to the server.\n");
if (bytesRead=recv(clientSocketFD, buffer, MAX_BUFFER_SIZE, 0) == -1) error("Cannot receive data from server,\n");
else if (bytesRead>0) printf("\nIncoming message (%d byte(s)) from %s:%d:\n\t%s\n", bytesRead, inet_ntoa(server.sin_addr), ntohs(server.sin_port), buffer);
while (1) {
// send message to server
printf("Enter message to send to server:\n");
scanf("%s", buffer);
//fflush(stdin);
printf("\nSending \"%s\" (%d byte(s)) to %s:%d\n", buffer, strlen(buffer), inet_ntoa(server.sin_addr), ntohs(server.sin_port));
send(clientSocketFD, buffer, strlen(buffer), 0);
if (strncasecmp(buffer, "quit", 4)==0) {
close(clientSocketFD);
printf("Server has terminated the connection.\n");
exit(EXIT_SUCCESS);
}
// Read data received from the server
if (bytesRead=recv(clientSocketFD, buffer, MAX_BUFFER_SIZE, 0) == -1) error("Cannot receive data from server,\n");
else if (bytesRead>0) printf("\nIncoming message (%d byte(s)) from %s:%d:\n\t%s\n", bytesRead, inet_ntoa(server.sin_addr), ntohs(server.sin_port), buffer);
bzero(buffer, strlen(buffer));
// clean up
//close(clientSocketFD);
}
}
Output for client
Code:
Socket v0.01
Select socket type (0=client, 1=Server)
0
Client type socket selected.
Enter message to send to server:
Hello, Server!
Sending "Hello," (6 byte(s)) to 127.0.0.1:10000
Enter message to send to server:
Sending "Server!" (7 byte(s)) to 127.0.0.1:10000
Server output
Code:
Socket v0.01
Select socket type (0=client, 1=Server)
1
Server type socket selected.
Client 127.0.0.1:37754 connected.
Message (6 byte(s)) received from the client(127.0.0.1:37754):
Hello,
Re: Server and Client are not working as it was intented too.
Comments:
1)
Code:
argv[0]="127.0.0.1";
argv[1]="10000";
argv pointer is used as input argument. It's not good habit to do like this.
2) Try to check all return code of each function. For example, in following code
you should check other return code (in this case return code 0).
Code:
if (bytesRead=recv(clientSocketFD, buffer, MAX_BUFFER_SIZE, 0) == -1) error("Cannot receive data from server,\n");
else if (bytesRead>0) printf("\nIncoming message (%d byte(s)) from %s:%d:\n\t%s\n", bytesRead, inet_ntoa(server.sin_addr), ntohs(server.sin_port), buffer);
3) Always put NULL after the end of received message. If you received 10
bytes of character, put NULL character at this position. Example:
Code:
iRcvLen = recv(iSocket, szBuf, sizeof(szBuf) -1, 0);
if(iRcvLen > 0) szBuf[iRcvLen] = '\0';
4) About your question:
4.1)
Quote:
Originally Posted by cloud1
1. How come my client does not receive the welcome message once it has established a
connection with the server?
Your client should receive the message. Please take attention in point 3)
4.2)
Quote:
Originally Posted by cloud1
2. What is the problem that is causing my client not to send the whole string as it was
specified by the user. For example the string "Hello, Server!" without the quotation
marks get send as two different packets instead of one. Look at "Output for client"
no quotation marks.
TCP is stream-based protocol, not message protocol. You have to combine
all incoming message. The easiest way is using select() to check whether
some message will be received.
4.3)
Quote:
Originally Posted by cloud1
3. Why does the server just hangs around after the client sends a packet to the server
and doesn't send anything back to the client as it was intended according to the
code?
Your server tries to accept other connection after sent() & recv(). Put accept()
outside while() loop if you want to make test program. If you want to make
real program, you need to consider how to handle multiple clients connection.
Henky
Re: Server and Client are not working as it was intented too.
Quote:
2) Try to check all return code of each function. For example, in following code
you should check other return code (in this case return code 0).
Code:
if (bytesRead=recv(clientSocketFD, buffer, MAX_BUFFER_SIZE, 0) == -1) error("Cannot receive data from server,\n");
else if (bytesRead>0) printf("\nIncoming message (%d byte(s)) from %s:%d:\n\t%s\n", bytesRead, inet_ntoa(server.sin_addr), ntohs(server.sin_port), buffer);
3) Always put NULL after the end of received message. If you received 10
bytes of character, put NULL character at this position. Example:
Code:
iRcvLen = recv(iSocket, szBuf, sizeof(szBuf) -1, 0);
if(iRcvLen > 0) szBuf[iRcvLen] = '\0';
4) About your question:
4.1)
Your client should receive the message. Please take attention in point 3)
I check the recv() against -1 because in socket.h it stated: Return the number read or -1 for errors. Anyway I fixed the code. It should be
Code:
if ((bytesRead=recv(clientSocketFD, buffer, MAX_BUFFER_SIZE, 0))==0) error("Cannot receive data from server,\n");
else if (bytesRead>0) {
buffer[strlen(buffer)]="\0"; // added after reading your comments
printf("\nIncoming message (%d byte(s)) from %s:%d:\n%s\n", bytesRead, inet_ntoa(server.sin_addr), ntohs(server.sin_port), buffer);
}
Quote:
4.2)
TCP is stream-based protocol, not message protocol. You have to combine
all incoming message. The easiest way is using select() to check whether
some message will be received.
I fixed the problem. I have to use
Code:
fgets(buffer, MAX_BUFFER_SIZE+1, stdin)
in order to get the whole phrase like "Hello, Server!" including the whitespace characters because scanf() terminate reading after it encounter a whitespace character.
Quote:
4.3)
Your server tries to accept other connection after sent() & recv(). Put accept()
outside while() loop if you want to make test program. If you want to make
real program, you need to consider how to handle multiple clients connection.
I tried putting the accept() outside the while() loop after I ran the program and realize that the server will just going to hang around and not performing any receiving and sending, but after doing this the server was working and performing the functions that I intended for the server to perform, but then I again I think that putting the accept() outside the while() loop was wrong, so I put it back into the while() loop, and then ask
other networking programmer(s) to decide whether is the right or wrong way.
But since you clarified for me. I understand it now.
Thank for all your help Henky.