/* Operating Systems Spring 2005 Sample TCP sockets client This client sends requests to a server that can lookup user's names given either a username or userid. The complete protocol is described in the file PROTOCOL */ #include #include #include #include #include /* socket specific definitions */ #include /* INET constants and stuff */ #include /* IP address conversion stuff */ #include /* gethostbyname */ #include #include #include "getline.h" /* here is code that attempts to create a tcp socket and connect to the server specified. No data is read or sent, this just creates the socket and connects to the server If everything works, this function returns a socket descriptor. Any errors are considered fatal (program exits). */ int create_tcp_connection(char *server_hostname,int port) { int sd; struct sockaddr_in skaddr; struct hostent *hp; /* used for name lookup */ /* create a socket IP protocol family (PF_INET) TCP protocol (SOCK_STREAM) */ if ((sd = socket( PF_INET, SOCK_STREAM, 0 )) < 0) { perror("Problem creating socket"); exit(1); } /* fill in an address structure that will be used to specify the address of the server we want to connect to address family is IP (AF_INET) server IP address is found by calling gethostbyname with the name of the server */ skaddr.sin_family = AF_INET; /* convert hostname to a network byte order binary IP address */ /* First try to convert using gethostbyname */ if ((hp = gethostbyname(server_hostname))!=0) { /* Name lookup was successful - copy the IP address */ memcpy( &skaddr.sin_addr.s_addr, hp->h_addr, hp->h_length); } else { /* Name lookup didn't work, try converting from dotted decimal */ if (inet_aton(server_hostname,&skaddr.sin_addr)==0) { printf("Invalid IP address: %s\n",server_hostname); exit(1); } } /* port must be in network byte order! */ skaddr.sin_port = htons(port); /* attempt to establish a connection with the server */ if (connect(sd,(struct sockaddr *) &skaddr,sizeof(skaddr)) < 0 ) { perror("Problem connecting to server"); exit(1); } return(sd); } /* Send a request */ int send_request(int server, char *type, char *arg) { char buff[100]; /* build the request line */ if (snprintf(buff,100,"%s %s\n",type,arg)>=100) { printf("Can't send - request is too long\n"); exit; } return(writeline(server,buff)); } /* When running the client, it must specify 3 command line values: server hostname or IP address server port number either a username or userid The client determines whether the request should be a username or userid request depending on whether the first character of the 3 argument is numeric */ int main(int argc, char **argv) { char *servername=NULL; int port=0; int sd; char buff[100]; if (argc!=4) { printf("usage: ./client server port username|userid\n"); return(1); } servername = argv[1]; port = atoi(argv[2]); /* connect to the server */ sd = create_tcp_connection(servername, port); /* determine whether this is a username or userid request */ if (isdigit(argv[3][0])) { /* first char is numeric - must be a userid */ if (send_request(sd,"userid",argv[3])<0) { printf("Error sending request\n"); exit(1); } } else { /* send username request */ if (send_request(sd,"username",argv[3])<0) { printf("Error sending request\n"); exit(1); } } /* get the response */ if (getline(sd,buff,100)<0) { printf("Error reading response\n"); exit(1); } if (strncmp(buff,"ERR",3)==0) { printf("Server indicates an error: %s\n",buff+3); } else if (strncmp(buff,"OK",2)==0) { printf("Success: %s\n",buff+2); } else { printf("Unknown response: %s\n",buff); } return(1); }