#include#define BUFSIZE 8192
#define DEFAULT_PORT 5320
enum {SMD_NAME,DST_IP,DST_PORT};
int main(int argc,char *argv[])
{
struct sockaddr_in server; //服务器地址
unsigned long dst_ip; //服务器IP地址
int port; //端口号
int s; //套接字的描述符
int n; //输入数据的字节数
char buf[BUFSIZE]; //接收缓
char cmd[BUFSIZE]; //发送缓
struct timeval tv; //select超时时间
fd_set readfd; //使用select检索出的描述符
//实际参数的检查
if(argc!=2 && argc!=3){
fprintf(stderr,"Usage: %s hostname[port]\n",argv[0]);
exit(EXIT_FAILURE);
}
//检索服务器的ip地址
if((dst_ip=inet_addr(argv[DST_IP]))==INADDR_NONE){
struct hostent *he; //主机信息
if((he=gethostbyname(argv[DST_IP]))==NULL){
fprintf(stderr,"gethostbyname error\n");
exit(EXIT_FAILURE);
}
memcpy((char *)&dst_ip,(char *)he->h_addr,sizeof(he->h_addr));
}
//检索服务器的端口号
if(argc==3){
if((port=atoi(argv[DST_PORT]))==0){
struct servent * se; //服务信息
if((se=getservbyname(argv[DST_PORT],"tcp"))!=NULL)
port=(int) ntohs((u_short)se->s_port);
else{
fprintf(stderr,"getservbyname error\n");
exit(EXIT_FAILURE);
}
}
}else
port=DEFAULT_PORT;
//使用TCP协议打开一个套接字
if((s=socket(AF_INET,SOCK_STREAM,0))<0){
perror("socket");
exit(EXIT_FAILURE);
}
//设定服务器的地址,建立一个连接
memset((char *)&server,0,sizeof(server));
server.sin_family=AF_INET;
server.sin_addr.s_addr=dst_ip;
server.sin_port=htons(port);
if(connect(s,(struct sockaddr *)&server,sizeof(server))<0){
perror("connect");
exit(EXIT_FAILURE);
}
printf("Connected to '%s'\n",inet_ntoa(server.sin_addr));
//客户机处理的主要子程序
while(1){
//select超时的设定
tv.tv_sec=600;
tv.tv_usec=0;
//标准输入,有无来自服务器的报文
FD_ZERO(&readfd);
FD_SET(0,&readfd);
FD_SET(s,&readfd);
if((select(s+1,&readfd,NULL,NULL,&tv))<=0){
fprintf(stderr,"\nTimeout\n");
break;
}
//标准输入
if(FD_ISSET(0,&readfd)){
if((n=read(0,buf,BUFSIZE-1))<=0)
break;
buf[n]='\n';
sscanf(buf,"%s",cmd);
if(strcmp(cmd,"quit")==0)
break;
if(send(s,buf,n,0)<=0)
break;
}
//服务器
if(FD_ISSET(s,&readfd)){
if((n=recv(s,buf,BUFSIZE-1,0))<=0){
fprintf(stderr,"connection closed.\n");
exit(EXIT_FAILURE);
}
buf[n]='\0';
printf("%s",buf);
fflush(stdout);
}
}
strcpy(buf,"quit");
send(s,buf,n,0);
close(s);
return EXIT_SUCCESS;
}