-
Server Client on UNIX
hi there
I'm trying to set up a client server system on unix.
i've got some troubles with my "write" and "read"
I want to send the data from the client like this
Code:
printf("Enter user's name:\t");
scanf("%s", name);
fflush(stdin);
write(hSocket, name, strlen(name));
and to receive it on the server with this:
Code:
read(hSocket, string, STRGLEN);
printf("%s", string);
The problem is the string I have on the server's side is not the same as the one I enter on the client's side (if I enter "qsdf" I get "qs5f")
And what's even more frustrating is that when I have my client with just
socket
connect
write
close
and my server with just
socket
bind
listen
accept
read
close
it works just fine!
Can anyone help me?
-
This link may offer some assistance. This may not be your issue, but reading this couldn't hurt. LINK
-
> read(hSocket, string, STRGLEN);
Check the return result - my guess is that you're not receiving all your data in a single message.
Networks can fragment data, so reassembly is YOUR problem.
Also, read() does not add a \0 onto the end of the data, so blindly doing
printf("%s", string);
will print whatever junk is in the end of string just beyond where read() finished storing data.
-
i've begun again from the very beginning
and it still doesn't work
I submit you my source code so you can tell me what's wrong
here's the code for the client:
Code:
// Main Function
main(int argc, char *argv[]){ /* argv[1] is server hostname */
register int hSocket; /* created socket (index to unix descriptor table) */
struct hostent *pHostInfo; /* pointer to host structure */
struct sockaddr_in Address; /* socket structure */
char c, name[100], string[STRGLEN];
int i;
/* look up the network address of server hostname */
pHostInfo = gethostbyname(argv[1]);
if( pHostInfo==0 ){
fprintf(stderr, "unknown host %s\n", argv[1]);
exit(1);
}
/* create socket in the Internet domain(AF_INET) that will be connection
oriented SOCK_STREAM. (connectionless is SOCK_DGRAM) 3rd argument indicated
default TCP/IP protocol */
printf("\nMaking a socket");
if( (hSocket = socket(AF_INET, SOCK_STREAM, 0)) <0 ){
perror("client: socket");
exit(1);
}
/* Create the address we will be connecting to. We use port
1234 but put it into network byte order.
Also we use bcopy to copy the network number */
Address.sin_family = AF_INET;
Address.sin_port = htons(APORT);
bcopy(pHostInfo->h_addr, &Address.sin_addr, pHostInfo->h_length);
/* Try to connect to the address.
For this to succeed, the server must already have bound
this address, and must have issued a listen() request. */
printf("\nConnecting to %s on port %d\n",pHostInfo,APORT);
if(connect(hSocket, (struct sockaddr *)&Address, sizeof(Address)) < 0){
perror("client: connect");
exit(1);
}
/* write the name of the user to the server */
for(i=0; i<STRGLEN; i++) /* clear string */
name[i]='\0';
printf("Enter your user's name:\t");
scanf("%[^\n]", name);
//send(hSocket, name, strlen(name), 0);
write(hSocket, name, strlen(name));
/* close socket */
printf("\nClosing socket\n");
if(close(hSocket) == SOCKET_ERROR)
{
printf("\nCould not close socket\n");
return 0;
}
}
and the server's code:
Code:
/* Main Function */
main(void){
char hostname[64]; /* local machine hostname */
char name[100], string[STRGLEN];
struct hostent *pHostInfo; /* gethostbyname return ptr. holds info about a machine*/
register int SocketDescriptor; /* socket descriptor, or -1 if error */
register int hSocket; /* created new socket for accept */
struct sockaddr_in AddressServer; /* socket structure */
struct sockaddr_in AddressClient; /* socket str. for accept*/
int AddressSize; /*size struct sockaddr_in */
int i;
/* look up the network address of server hostname */
gethostname(hostname, sizeof(hostname));
/* look up the network address of the host.*/
if((pHostInfo = gethostbyname(hostname)) == NULL){
fprintf(stderr, "%s: unknown host\n", hostname);
exit(1);
}
/* create socket in Internet domain(AF_INET), that is connection oriented
(SOCK_STREAM) rather than connectionless (SOCK_DGRAM), arg3=0 for default
TCP/IP protocol*/
printf("\nStarting server");
printf("\nMaking socket");
if(( SocketDescriptor = socket(AF_INET, SOCK_STREAM, 0) ) < 0){
perror("server: socket"); exit(1);
}
/* Create the address to connecting to. We use port APORT but put it into
network byte order. Also we use bcopy to copy the network number. */
bzero(&AddressServer, sizeof(AddressServer)); /*bzero Is a macro that fills memory with the number of zeros specified by length. */
AddressServer.sin_family = AF_INET; /* IP protocol */
AddressServer.sin_addr.s_addr = INADDR_ANY;
AddressServer.sin_port = htons(APORT); /* htons converts 16-bit quantities from host to network byte order */
bcopy(pHostInfo->h_addr, &AddressServer.sin_addr, pHostInfo->h_length);
/* Try to bind(address and port no.)to socket SocketDescriptor */
printf("\nBinding to port %d",APORT);
if(bind(SocketDescriptor, (struct sockaddr *)&AddressServer, sizeof(AddressServer)) < 0){
perror("server: bind");
exit(1);
}
/* server ready, listen on socket SocketDescriptor max 5 requests queued*/
printf("\nMaking a listen queue of 5 elements");
if(listen(SocketDescriptor, 5) < 0){
perror("server: listen");
exit(1);
}
/* Accept connections then fork hSocket (new socket) that will be connected
to the client. AddressClient will contain the IP address of the client. */
bzero(&AddressClient, sizeof(AddressClient));
AddressSize = sizeof(AddressClient);
printf("\nWaiting for a connection\n");
if((hSocket = accept(SocketDescriptor, (struct sockaddr *)&AddressClient, &AddressSize))<0){
perror("server: accept");
exit(1);
}
/* Read the name of the user */
for(i=0; i<STRGLEN; i++) /* clear string */
name[i]='\0';
//recv(hSocket, name, strlen(name), 0);
i=read(hSocket, name, strlen(name));
printf("\n%d\n%s\n", i, name);
/* close socket */
printf("\nClosing the socket\n");
if(close(SocketDescriptor) == SOCKET_ERROR)
{
printf("\nCould not close socket\n");
exit(-1);
}
}
and what happens is that the server tries to read and close the socket even before the client writes something
(on my screen I've got:
0
closing the socket
Enter your user's name: )
Please help me
-
Next time, can you remove the italics?
> i=read(hSocket, name, strlen(name));
C'mon, you've just cleared the string, so what do you expect strlen() to return?
Like this...
i=read(hSocket, name, sizeof(name)-1);
if ( i > 0 ) name[i] = '\0';
-
all right, the send/receive works just fine, thanks to you
now I'm trying to send the list of the users from the server to the client. I've set up a function which sends (or rather should send) to the client the total number of users, all the names of the users and their numbers. I've created 1 user to check that my function works.
And it doesn't.
here's my source code:
client:
Code:
#include <sys/types.h> /* required include files */
#include <sys/socket.h>
#include <netinet/in.h> /* bind in internet domain */
#include <netdb.h>
#include <string.h>
#include <stdio.h>
#include <stdlib.h>
#include <unistd.h>
#define SOCKET_ERROR -1
#define STRGLEN 100 /* message string length */
const int APORT = 1234; /* chosen port number */
// FUNCTIONS
//New lines
/* Function receive_all_users
this function reads the list of all the users */
void receive_all_users(int s){
int n=1, i;
char string[STRGLEN];
int num, nRecv;
for(i=0;i<STRGLEN;i++)
string[i]='\0'; /*init string*/
nRecv=recv(s, string, sizeof(string)-1, 0);
if(nRecv>0)
string[nRecv]='\0';
sscanf(string, "%d", &num);
if(num!=0){
while(n<=num){
for(i=0;i<STRGLEN;i++)
string[i]='\0'; /*init string*/
nRecv=recv(s, string, strlen(string), 0);
n++;
}
}
else
printf("There is no user\n");
}
/* Function main */
main(int argc, char *argv[]) /* argv[1] is server hostname */{
char string[STRGLEN]; /* message string */
register int s; /* created socket (index to unix descriptor table) */
struct hostent *hp; /* pointer to host structure */
struct sockaddr_in sin; /* socket structure */
float number;
int i; /* loop counter */
int selection; /* menu choice */
/* look up the network address of server hostname */
hp = gethostbyname(argv[1]);
if( hp==0 ){
fprintf(stderr, "unknown host %s\n", argv[1]);
exit(1);
}
/* create socket in the Internet domain(AF_INET) that will
be connection oriented SOCK_STREAM. (connectionless is
SOCK_DGRAM) 3rd argument indicated default TCP/IP protocol */
if( (s = socket(AF_INET, SOCK_STREAM, 0)) <0 ){
perror("client: socket");
exit(1);
}
/* Create the address we will be connecting to We use port
1234 but put it into network byte order.
Also we use bcopy to copy the network number */
sin.sin_family = AF_INET;
sin.sin_port = htons(APORT);
bcopy(hp->h_addr, &sin.sin_addr, hp->h_length);
/* Try to connect to the address.
For this to succeed, the server must already have bound
this address, and must have issued a listen() request. */
if(connect(s, (struct sockaddr *)&sin, sizeof(sin)) < 0){
perror("client: connect");
exit(1);
}
/* write the name of the user to the server */
printf("Enter your user's name\t");
for(i=0; i<STRGLEN; i++)string[i]='\0'; /* clear string */
scanf("%[^\n]", string);
send(s, string, strlen(string), 0);
//printf("***Debug Client: data sent = %s***\n", string);
//New lines
if(strcmp(string, "admin")==0){ //case user = administrator
receive_all_users(s);
}
/* close connection, since were finished on both sides */
close(s);
}
server:
Code:
#include <sys/types.h> /* required include files */
#include <sys/socket.h>
#include <netinet/in.h>
#include <netdb.h>
#include <stdlib.h>
#include <stdio.h>
#include <string.h>
#include <ctype.h>
#include <unistd.h>
#define SOCKET_ERROR -1
#define STRGLEN 100 /* message string length */
const int APORT = 1234; /* port number */
//New lines
//DATA STRUCTURES
typedef struct{
char nameUser[100];
int numUser;
}user;
typedef struct userStruct{
user u;
struct userStruct* next;
}userknot;
typedef struct{
userknot* start;
userknot* end;
int totalUsers;
}userslist;
//FUNCTIONS
/* Function create_users_list
This function initializes the users list */
userslist* create_users_list(){
userslist* list;
list=(userslist*)malloc(sizeof(userslist));
if(list==NULL)return NULL;
list->start=list->end=NULL;
return list;
}
/* Function send_all_users
this function send the list of all the users to the client */
void send_all_users(int s, userslist* ul){
userknot* uk;
int n=1, i, nSend;
char string[STRGLEN];
int num=ul->totalUsers;
for(i=0;i<STRGLEN;i++)
string[i]='\0'; /*init string*/
sprintf(string, "%d", num);
nSend=send(s, string, sizeof(string),0);
/*if(nSend>0)
string[nSend]='\0';*/
if(num!=0){
uk=ul->start;
while(n<=num){
for(i=0;i<STRGLEN;i++)
string[i]='\0'; /*init string*/
strcpy(string, uk->u.nameUser);
nSend=send(s, string, sizeof(string),0);
uk=uk->next;
n++;
}
}
}
/* Function main */
main(){
char string[STRGLEN];
int fromlen;
char hostname[64]; /* local machine hostname */
struct hostent *hp; /* gethostbyname return ptr */
register int s; /* socket descriptor, or -1 if error */
register int ns; /* created new socket for accept */
struct sockaddr_in sin; /* socket structure */
struct sockaddr_in fsin; /* socket str. for accept*/
float number=0.0;
int i; /* loop counter */
int selection; /* menu choice */
int num_user, nRecv, nSend;
userslist* ulist;
fileslist* flist;
userknot* str_userknot;
/* first need to know our hostname. */
gethostname(hostname, sizeof(hostname));
/* Next look up the network address of our host.*/
if((hp = gethostbyname(hostname)) == NULL){
fprintf(stderr, "%s: unknown host\n", hostname);
exit(1);
}
/* create socket in Internet domain(AF_INET), that is
connection oriented (SOCK_STREAM) rather than
connectionless (SOCK_DGRAM),
arg3=0 for default TCP/IP protocol*/
if(( s = socket(AF_INET, SOCK_STREAM, 0) ) < 0){
perror("server: socket");
exit(1);
}
/* Create the address to connecting to. We use port
APORT but put it into network byte order.
Also we use bcopy to copy the network number. */
bzero(&sin, sizeof(sin));
sin.sin_family = AF_INET; /* IP protocol */
/* sin.sin_addr.s_addr = INADDR_ANY;*/
sin.sin_port = htons(APORT);
bcopy(hp->h_addr, &sin.sin_addr, hp->h_length);
/* Try to bind(address and port no.)to socket s */
if(bind(s, (struct sockaddr *)&sin, sizeof(sin)) < 0){
perror("server: bind");
exit(1);
}
/* server ready, listen on socket s max 5 requests queued*/
if(listen(s, 5) < 0) {
perror("server: listen");
exit(1);
}
/* Accept connections then fork ns (new socket) that
will be connected to the client. fsin will contain
the IP address of the client. */
bzero(&fsin, sizeof(fsin));
fromlen = sizeof(fsin);
if((ns = accept(s, (struct sockaddr *)&fsin, &fromlen))<0){
perror("server: accept");
exit(1);
}
ulist=create_users_list(); //Initialization of the users list
if(ulist==NULL){
printf("Impossible to allocate a users list");
exit(-1); //Exit the program
}
//New lines
/*create a user*/
str_userknot=(userknot*)malloc(sizeof(userknot));
if(str_userknot==NULL)
printf("Can't add a new user");
else{
strcpy(str_userknot->u.nameUser, "user1");
str_userknot->u.numUser=1;
ulist->start=str_userknot;
ulist->end=str_userknot;
ulist->end->next=NULL;
ulist->totalUsers=1;
}
/* Read the name of the user */
for(i=0;i<STRGLEN;i++)string[i]='\0'; /*init string*/
recv(ns, string, STRGLEN, 0);
//printf("***Debug Server: received = %s ***\n", string);
//New lines
if(strcmp(string, "admin")==0){
send_all_users(ns, ulist);
}
/* We can simply use close() to terminate the
connection, since we're done with both sides */
close(s);
}
What happens is that the client receives nothing (nRecv=0 each time)
What's wrong?