Thread: Server Client on UNIX

  1. #1
    Registered User
    Join Date
    Oct 2003
    Posts
    17

    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?

  2. #2
    Registered User Azuth's Avatar
    Join Date
    Feb 2002
    Posts
    236
    This link may offer some assistance. This may not be your issue, but reading this couldn't hurt. LINK
    Demonographic rhinology is not the only possible outcome, but why take the chance

  3. #3
    and the hat of int overfl Salem's Avatar
    Join Date
    Aug 2001
    Location
    The edge of the known universe
    Posts
    39,659
    > 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.
    If you dance barefoot on the broken glass of undefined behaviour, you've got to expect the occasional cut.
    If at first you don't succeed, try writing your phone number on the exam paper.

  4. #4
    Registered User
    Join Date
    Oct 2003
    Posts
    17
    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

  5. #5
    and the hat of int overfl Salem's Avatar
    Join Date
    Aug 2001
    Location
    The edge of the known universe
    Posts
    39,659
    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';
    If you dance barefoot on the broken glass of undefined behaviour, you've got to expect the occasional cut.
    If at first you don't succeed, try writing your phone number on the exam paper.

  6. #6
    Registered User
    Join Date
    Oct 2003
    Posts
    17
    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?

Popular pages Recent additions subscribe to a feed

Similar Threads

  1. server client application - (i really need your help)
    By sarahnetworking in forum C Programming
    Replies: 3
    Last Post: 03-01-2008, 10:54 PM
  2. Client works on a LAN but don't send all the data
    By Niara in forum Networking/Device Communication
    Replies: 9
    Last Post: 01-04-2007, 04:44 PM
  3. Where's the EPIPE signal?
    By marc.andrysco in forum Networking/Device Communication
    Replies: 0
    Last Post: 12-23-2006, 08:04 PM
  4. Server and Client process
    By wise_ron in forum Networking/Device Communication
    Replies: 1
    Last Post: 10-07-2006, 01:11 AM
  5. Unicode vurses Non Unicode client server application with winsock2 query?
    By dp_76 in forum Networking/Device Communication
    Replies: 0
    Last Post: 05-16-2005, 07:26 AM