Hi guys,

I am doing a TCP/IP time server/client. I already wrote the two programs but when I run them I don't get any output. Simply, the idea is the client asks the server for Time or Date and the server has to respond and terminate after the second request.

On the server side, I have to print the server IP, port, request type and finally the client IP and port.

On the client side, I have to print the client port, server's port, server's IP and the time or date.

I used this code to run the programs:
gcc -o serv server.c -lsocket -lnsl -lresolv
gcc -o cli client.c -lsocket -lnsl -lresolv

One more thing, this is my first time to write socket codes so i have a problem with finding the client port so please I'd appreciate any help.

Thanks :-)

server.c

client.c

You should post the code in code tags (unless it is actually too big to reasonably view on a normal size screen) instead of attaching it. I'm assuming that it is pretty small from your project description. Anyway I'll take a look at it since I recently did a similar project. Note that I'm not really much of a C developer so take any advice at your own risk or wait for someone else to respond. Here is his code for anyone interested.

Server.c:

#include <stdio.h>
#include <stdlib.h>
#include <unistd.h>
#include <errno.h>
#include <string.h>
#include <sys/types.h>
#include <sys/socket.h>
#include <netinet/in.h>
#include <netdb.h>
#include <arpa/inet.h>
#include <time.h>

#define SERVERPORT "21111" 
#define MAXLEN 100


void *get_in_addr(struct sockaddr *sa)
{
  if (sa->sa_family == AF_INET) {
    return &(((struct sockaddr_in*)sa)->sin_addr);
  }

  return &(((struct sockaddr_in6*)sa)->sin6_addr);
}


main() 
{ 
	int sockfd, newfd;    // listen on sockfd, new connection on newfd
	unsigned int len;
	socklen_t sin_size;
	char msg[80];
	char buf[MAXLEN];
	int st, rv;
	struct addrinfo hints, *serverinfo, *p; 
	struct sockaddr_storage client;
	char s[INET6_ADDRSTRLEN];
	time_t rawtime;

	
	
	
  //zero struct	
  memset(&hints,0,sizeof(hints));
  hints.ai_family = AF_UNSPEC;
  hints.ai_socktype = SOCK_STREAM;
  hints.ai_flags = AI_PASSIVE;

  if((rv = getaddrinfo("localhost", SERVERPORT, &hints, &serverinfo ) != 0)){
    perror("getaddrinfo");
    exit(-1);
  }

   // loop through all the results and bind to the first we can
  for( p = serverinfo; p != NULL; p = p->ai_next){
    if( (sockfd = socket( p->ai_family, p->ai_socktype, p->ai_protocol )) == -1 ) {
      perror("socket");
      continue;
    }
    
    if(bind(sockfd, p->ai_addr, p->ai_addrlen) == -1){
      close(sockfd);
      perror("bind");
      continue;
    }
    
    break;
  }

  if( p == NULL ){
    perror("Fail to bind");
	  
  }
	

  // all done with this structure, free the memory
  freeaddrinfo(serverinfo);
  
  if( listen(sockfd,5) == -1 ){
    perror("Listen");
    exit(-1);
  }

  len = sizeof client;

  while(1){
    if( ( newfd = accept(sockfd, (struct sockaddr *)&client, &len) ) == -1 ){
      perror("Accept");
      exit(-1);
    }

    if( (rv = recv(newfd, buf, MAXLEN-1, 0 )) == -1) {
      perror("Recv");
      exit(-1);
    }
	  struct sockaddr_in *clientAddr = ( struct sockaddr_in *) get_in_addr((struct sockaddr *)&client);
	  inet_ntop(client.ss_family, clientAddr, s, sizeof s);
	  printf("Calender server has TCP Port %d and IP address %d ", SERVERPORT); // server IP is missing
	  printf("Query type is %s\n", buf);  // Time or Date
	  
	  struct tm * timeinfo; // get the time
	  time ( &rawtime );
	  timeinfo = localtime ( &rawtime );
	  
	  if (buf == "TIME"){
	  strftime (msg,80,"Time is: %H::%M::%S",timeinfo);
	  }
	else {
	strftime (msg,80,"Date is: %B::%d::%Y",timeinfo);
	}
	  
    if( ( st = send(newfd, msg, strlen(msg), 0)) == -1 ) {
      perror("Send");
      exit(-1);
    }
    printf("Send Time/Date to client with IP %s and port %d\n", s, ntohs(clientAddr->sin_port) );

	  
	

	  
	 return 0;
	
    close(newfd);
  }

}

Client.c:

#include <stdio.h>
#include <stdlib.h>
#include <unistd.h>
#include <errno.h>
#include <string.h>
#include <netdb.h>
#include <sys/types.h>
#include <netinet/in.h>
#include <sys/socket.h>
#include <arpa/inet.h>
#include <time.h>

#define PORT "21111" // the port client will be connecting to
#define MAXLEN 100 // max number of bytes we can get at once

// get sockaddr, IPv4 or IPv6:
void *get_in_addr(struct sockaddr *sa)
{
	if (sa->sa_family == AF_INET) {
		return &(((struct sockaddr_in*)sa)->sin_addr);
	}
	return &(((struct sockaddr_in6*)sa)->sin6_addr);
}

int main(int argc, char *argv[])
{
	int sockfd, numbytes;
	char msg [80];
	char buf[MAXLEN];
	struct addrinfo hints, *servinfo, *p;
	int rv;
	char s[INET6_ADDRSTRLEN];
	if (argc != 2) {
		fprintf(stderr,"usage: client hostname\n");
		exit(1);
	}
	
	memset(&hints, 0, sizeof hints);
	hints.ai_family = AF_INET;
	hints.ai_socktype = SOCK_STREAM;
	
	if ((rv = getaddrinfo("localhost", PORT, &hints, &servinfo)) != 0) {
		fprintf(stderr, "getaddrinfo: %s\n", gai_strerror(rv));
		return 1;
	}
	// loop through all the results and connect to the first we can
	for(p = servinfo; p != NULL; p = p->ai_next) {
		if ((sockfd = socket(p->ai_family, p->ai_socktype,
							 p->ai_protocol)) == -1) {
			perror("client: socket");
			continue;
		}
		if (connect(sockfd, p->ai_addr, p->ai_addrlen) == -1) {
			close(sockfd);
			perror("client: connect");
			continue;
		}
		break;
	}
	if (p == NULL) {
		fprintf(stderr, "client: failed to connect\n");
		return 2;
	}
	inet_ntop(p->ai_family, get_in_addr((struct sockaddr *)p->ai_addr),
			  s, sizeof s);
	printf("My TCP port %d\n Server's Port %d And IP %s\n", PORT, s); // TCP Port is missing
	
	freeaddrinfo(servinfo); // all done with this structure
	if ((numbytes = recv(sockfd, msg, MAXLEN-1, 0)) == -1) {
		perror("recv");
		exit(1);
	}
	if (buf == "TIME") {
	printf("Time: '%s'\n",msg);
	}
	else {
	printf("Date: '%s'\n",msg);
	}
	close(sockfd);
	return 0;
}

Ok, so here's the deal. I was able to connect to your server using telnet which, to me, indicates that your server is working more than you thought. All I did was compile & run your server, then say telnet localhost 21111. I compiled with just "gcc server.c", ran the executable, then issued the telnet command.

edit:
I also ran both of your programs like so:
gcc -o Server server.c
gcc -o Client client.c
Server
(in other terminal now)
Client localhost

Running it as I did above gave me output "My TCP port is (some number here)" then it seg faulted. Not what you'd want but better than not running at all I guess.

Thank you & I really appreciate it, but why when I do:
cli TIME or cli DATE (on another terminal while the server is running) I don't get any response from the server?

Is there something wrong with my client code or server code?

Thank you & I really appreciate it, but why when I do:
cli TIME or cli DATE (on another terminal while the server is running) I don't get any response from the server?

Is there something wrong with my client code or server code?

Can someone tell me what's wrong with my client code?

There are 2 big mistakes in your program
1. In the printf that you do on line 66 in the client program is causing a seg fault because of parameter mis match. Comment out that line or put the proper parameters
2. The server is waiting for the client to send Time/ Date. If nothing is received the server just waits without doing anything. But your client does not send that data.

is this

if (buf == "TIME") {
    printf("Time: '%s'\n",msg);
}

the proper way to compare strings in C?

There are 2 big mistakes in your program
1. In the printf that you do on line 66 in the client program is causing a seg fault because of parameter mis match. Comment out that line or put the proper parameters
2. The server is waiting for the client to send Time/ Date. If nothing is received the server just waits without doing anything. But your client does not send that data.

Thank you a lot.. I already fix the problem in line 66 & here is my new client codes

#include <stdio.h>
#include <stdlib.h>
#include <unistd.h>
#include <errno.h>
#include <string.h>
#include <netdb.h>
#include <sys/types.h>
#include <netinet/in.h>
#include <sys/socket.h>
#include <arpa/inet.h>
#include <time.h>

#define PORT "21708" // the port client will be connecting to
#define MAXLEN 100 // max number of bytes we can get at once

// get sockaddr, IPv4 or IPv6:
void *get_in_addr(struct sockaddr *sa)
{
	if (sa->sa_family == AF_INET) {
		return &(((struct sockaddr_in*)sa)->sin_addr);
	}
	return &(((struct sockaddr_in6*)sa)->sin6_addr);
}

int main(int argc, char *argv[])
{
	int sockfd, rs, ss;
	char msg [80];
	char buf[MAXLEN];
	struct addrinfo hints, *servinfo, *p;
	int rv;
	char s[INET6_ADDRSTRLEN];
	if (argc != 2) {
		fprintf(stderr,"usage: client hostname\n");
		exit(1);
	}
	
	memset(&hints, 0, sizeof hints);
	hints.ai_family = AF_INET;
	hints.ai_socktype = SOCK_STREAM;
	
	if ((rv = getaddrinfo("nunki.usc.edu", PORT, &hints, &servinfo)) != 0) {
		fprintf(stderr, "getaddrinfo: %s\n", gai_strerror(rv));
		return 1;
	}
	// loop through all the results and connect to the first we can
	for(p = servinfo; p != NULL; p = p->ai_next) {
		if ((sockfd = socket(p->ai_family, p->ai_socktype, p->ai_protocol)) == -1) {
			perror("client: socket");
			continue;
		}
		if (connect(sockfd, p->ai_addr, p->ai_addrlen) == -1) {
			close(sockfd);
			perror("client: connect");
			continue;
		}
		break;
	}
	if (p == NULL) {
		fprintf(stderr, "client: failed to connect\n");
		return 2;
	}
	inet_ntop(p->ai_family, get_in_addr((struct sockaddr *)p->ai_addr),
			  s, sizeof s);
	
	
	freeaddrinfo(servinfo); // all done with this structure
	
	
	if ((ss = send(sockfd, buf, MAXLEN-1, 0)) == -1) { // send query
		perror("send");
		exit(1);
	
		
	if ((rs = recv(sockfd, msg, MAXLEN-1, 0)) == -1) { // recieve date or time
		perror("recv");
		exit(1);
		
		
	}
		printf("My TCP port %d\n Server's Port %d And IP %s\n", PORT, s);
		
	// if (buf == "time") {
	printf("%s \n",msg);
	// }
	// else {
	// printf("%s \n",msg);
	// }
		
	close(sockfd);
	}
	return 0;
}

The server works fine but when I execute the client and I write:
cli time // cli here is the output file of client.c

I don't get the output that I want, I just got segmentation fault. can u tell me what's wrong?

is this

if (buf == "TIME") {
    printf("Time: '%s'\n",msg);
}

the proper way to compare strings in C?

well, when I compile it and I didn't get any error, I thought it's right.. but I changed it to this now. Is it correct like this?

char time[]="TIME"
if ( strcmp(buf, time) == 0 )
   {
strftime (msg,80,"Time is: %H::%M::%S",timeinfo);
   }
   else
   {
     strftime (msg,80,"Date is: %B::%d::%Y",timeinfo);

Thanks!

Thank you a lot.. I already fix the problem in line 66 & here is my new client codes

#include <stdio.h>
#include <stdlib.h>
#include <unistd.h>
#include <errno.h>
#include <string.h>
#include <netdb.h>
#include <sys/types.h>
#include <netinet/in.h>
#include <sys/socket.h>
#include <arpa/inet.h>
#include <time.h>

#define PORT "21708" // the port client will be connecting to
#define MAXLEN 100 // max number of bytes we can get at once

// get sockaddr, IPv4 or IPv6:
void *get_in_addr(struct sockaddr *sa)
{
	if (sa->sa_family == AF_INET) {
		return &(((struct sockaddr_in*)sa)->sin_addr);
	}
	return &(((struct sockaddr_in6*)sa)->sin6_addr);
}

int main(int argc, char *argv[])
{
	int sockfd, rs, ss;
	char msg [80];
	char buf[MAXLEN];
	struct addrinfo hints, *servinfo, *p;
	int rv;
	char s[INET6_ADDRSTRLEN];
	if (argc != 2) {
		fprintf(stderr,"usage: client hostname\n");
		exit(1);
	}
	
	memset(&hints, 0, sizeof hints);
	hints.ai_family = AF_INET;
	hints.ai_socktype = SOCK_STREAM;
	
	if ((rv = getaddrinfo("nunki.usc.edu", PORT, &hints, &servinfo)) != 0) {
		fprintf(stderr, "getaddrinfo: %s\n", gai_strerror(rv));
		return 1;
	}
	// loop through all the results and connect to the first we can
	for(p = servinfo; p != NULL; p = p->ai_next) {
		if ((sockfd = socket(p->ai_family, p->ai_socktype, p->ai_protocol)) == -1) {
			perror("client: socket");
			continue;
		}
		if (connect(sockfd, p->ai_addr, p->ai_addrlen) == -1) {
			close(sockfd);
			perror("client: connect");
			continue;
		}
		break;
	}
	if (p == NULL) {
		fprintf(stderr, "client: failed to connect\n");
		return 2;
	}
	inet_ntop(p->ai_family, get_in_addr((struct sockaddr *)p->ai_addr),
			  s, sizeof s);
	
	
	freeaddrinfo(servinfo); // all done with this structure
	
	
	if ((ss = send(sockfd, buf, MAXLEN-1, 0)) == -1) { // send query
		perror("send");
		exit(1);
	
		
	if ((rs = recv(sockfd, msg, MAXLEN-1, 0)) == -1) { // recieve date or time
		perror("recv");
		exit(1);
		
		
	}
		printf("My TCP port %d\n Server's Port %d And IP %s\n", PORT, s);
		
	// if (buf == "time") {
	printf("%s \n",msg);
	// }
	// else {
	// printf("%s \n",msg);
	// }
		
	close(sockfd);
	}
	return 0;
}

The server works fine but when I execute the client and I write:
cli time // cli here is the output file of client.c

I don't get the output that I want, I just got segmentation fault. can u tell me what's wrong?

Do you have to put localhost when you execute the client program ?

you are write, it's localhost for both server and client. I was testing it on another server.

Client Codes:

#include <stdio.h>
#include <stdlib.h>
#include <unistd.h>
#include <errno.h>
#include <string.h>
#include <netdb.h>
#include <sys/types.h>
#include <netinet/in.h>
#include <sys/socket.h>
#include <arpa/inet.h>
#include <time.h>

#define PORT "21708" // the port client will be connecting to
#define MAXLEN 100 // max number of bytes we can get at once

// get sockaddr, IPv4 or IPv6:
void *get_in_addr(struct sockaddr *sa)
{
	if (sa->sa_family == AF_INET) {
		return &(((struct sockaddr_in*)sa)->sin_addr);
	}
	return &(((struct sockaddr_in6*)sa)->sin6_addr);
}

int main(int argc, char *argv[])
{
	int sockfd, rs, ss;
	char msg [80];
	char buf[MAXLEN];
	struct addrinfo hints, *servinfo, *p;
	int rv;
	char s[INET6_ADDRSTRLEN];
	if (argc != 2) {
		fprintf(stderr,"usage: client hostname\n");
		exit(1);
	}
	
	memset(&hints, 0, sizeof hints);
	hints.ai_family = AF_INET;
	hints.ai_socktype = SOCK_STREAM;
	
	if ((rv = getaddrinfo("localhost", PORT, &hints, &servinfo)) != 0) {
		fprintf(stderr, "getaddrinfo: %s\n", gai_strerror(rv));
		return 1;
	}
	// loop through all the results and connect to the first we can
	for(p = servinfo; p != NULL; p = p->ai_next) {
		if ((sockfd = socket(p->ai_family, p->ai_socktype, p->ai_protocol)) == -1) {
			perror("client: socket");
			continue;
		}
		if (connect(sockfd, p->ai_addr, p->ai_addrlen) == -1) {
			close(sockfd);
			perror("client: connect");
			continue;
		}
		break;
	}
	if (p == NULL) {
		fprintf(stderr, "client: failed to connect\n");
		return 2;
	}
	inet_ntop(p->ai_family, get_in_addr((struct sockaddr *)p->ai_addr),
			  s, sizeof s);
	
	
	freeaddrinfo(servinfo); // all done with this structure
	
	
	if ((ss = send(sockfd, buf, MAXLEN-1, 0)) == -1) { // send query
		perror("send");
		exit(1);
	
		
	if ((rs = recv(sockfd, msg, MAXLEN-1, 0)) == -1) { // recieve date or time
		perror("recv");
		exit(1);
		
		
	}
		printf("My TCP port %d\n Server's Port %d And IP %s\n", PORT, s);
		
	// if (buf == "time") {
	printf("%s \n",msg);
	// }
	// else {
	// printf("%s \n",msg);
	// }
		
	close(sockfd);
	}
	return 0;
}

The problem is I don't understand how does the client work? when I write cli TIME, does the client store TIME in the buf or in argv[]? I want to store it in buf so I can send it to the server.

Can u explain this to me?

It stores it in argv[1] if you execute the program this way
./client TIME
It stores it in argv[2] if you execute the program this way
./client localhost TIME

Why did you think TIME would be stored in the buff array ?

It stores it in argv[1] if you execute the program this way
./client TIME
It stores it in argv[2] if you execute the program this way
./client localhost TIME

Why did you think TIME would be stored in the buff array ?

I was confused because it's the first time I used this main(int argc, char *argv[])

so there is no pint of send buf to the server? I have to move argv[] to buf and send it or I can just send it directly?

ok if I write again client DATE, would it store it in argv[2] or it will write over argv[1] because I have to asked the server for time and date before the server terminate.

I really appreciate ur help, thanks alot :)

Thanks a lot, that was very helpful. Finally, both of them worked but they gave me different numbers for the port of the server though it's defined to be a specific number?

Do you have any idea why?

Last thing, If I want to make my server terminate after accepting two calls; how can I use the fork function? & should I use it after accept?

Are you printing on the server like this ?

printf("Calender server has TCP Port %d and IP address %d ", SERVERPORT); // server IP is missing

Then the problem is that printf has just one argument but 2 "%d", so the first %d will print SERVERPORT and the other one will print garbage

You will notice that in the server you have written a while(1). This means that the server can serve an infinite number of requests. If you want to just server any 2 requests then change the while(1) to for(i=0;i<2;i++)

Are you printing on the server like this ?

printf("Calender server has TCP Port %d and IP address %d ", SERVERPORT); // server IP is missing

Then the problem is that printf has just one argument but 2 "%d", so the first %d will print SERVERPORT and the other one will print garbage

You will notice that in the server you have written a while(1). This means that the server can serve an infinite number of requests. If you want to just server any 2 requests then change the while(1) to for(i=0;i<2;i++)

Thank you very much! It's working perfectly now. I really appreciate your help.

You are welcome ...

Be a part of the DaniWeb community

We're a friendly, industry-focused community of developers, IT pros, digital marketers, and technology enthusiasts meeting, networking, learning, and sharing knowledge.