重复性服务器客户机编程

1. Linux 环境下验证下列程序。 

   /*   

1、重复性服务器程序。等候客户连接,一旦连接则显示客户的地址,然后接收

来自该客户的信息(字符串) 。每当收到一个字符串,则显示该字符串,并将字符串

反转,再将反转的字符发回客户。之后,继续等待接收该客户的信息直至该客户关

闭连接。完成与该客户交互后,服务器开始等待下一客户,并重复上述过程。 

2、客户端程序。首先与相应服务器连接。然后接收用户从标准输入(键盘)输

入的字符串,再将字符串发送给服务器,接收服务器发回的信息并显示。之后,继

续等待用户输入直至用户输入 Ctrl-D。当收到用户输入 Ctrl-D 后,客户关闭连接并

退出。 

/* client.c */ 

  #include <stdio.h>  

  #include <unistd.h> 

  #include <strings.h> 

  #include <sys/types.h>  

  #include <sys/socket.h>  

  #include <netinet/in.h>  

  #include <netdb.h>            /* netbd.h is needed for struct hostent =) */  

  #define PORT 1234   /* Open Port on Remote Host */  

  #define MAXDATASIZE 100   /* Max number of bytes of data */  

  void process(FILE *fp, int sockfd); 

  char* getMessage(char* sendline,int len, FILE* fp); 

 

  int main(int argc, char *argv[])  

  {  

  int fd;   /* files descriptors */  

  struct hostent *he;         /* structure that will get information about remote host */  

  struct sockaddr_in server;  /* server's address information */  

 

  if (argc !=2) {        

     printf("Usage: %s <IP Address>\n",argv[0]);  

     exit(1);  

     }  

 

  if ((he=gethostbyname(argv[1]))==NULL){ /* calls gethostbyname() 

*/  

     printf("gethostbyname() error\n");  

     exit(1);  

     }  

 

  if  ((fd=socket(AF_INET,  SOCK_STREAM,  0))==-1){  /*  calls  socket() 

*/  

     printf("socket() error\n");  

     exit(1);  

     }  

 

  bzero(&server,sizeof(server)); 

  server.sin_family = AF_INET;  

  server.sin_port = htons(PORT); /* htons() is needed again */  

  server.sin_addr = *((struct in_addr *)he->h_addr);   

 

  if(connect(fd, (struct sockaddr *)&server,sizeof(struct 

sockaddr))==-1){ /* calls connect() */  

     printf("connect() error\n");  

     exit(1);  

     }  

 

  process(stdin,fd); 

 

  close(fd);   /* close fd */   

  }  

 

  void process(FILE *fp, int sockfd) 

  { 

  char sendline[MAXDATASIZE], recvline[MAXDATASIZE]; 

  int numbytes; 

 

  printf("Connected to server. \n"); 

  /* send name to server */ 

  printf("Input name : "); 

  if ( fgets(sendline, MAXDATASIZE, fp) == NULL) { 

     printf("\nExit.\n"); 

     return; 

     } 

  send(sockfd, sendline, strlen(sendline),0); 

 

  /* send message to server */   

  while (getMessage(sendline, MAXDATASIZE, fp) != NULL) { 

     send(sockfd, sendline, strlen(sendline),0); 

      if ((numbytes = recv(sockfd, recvline, MAXDATASIZE,0)) == 0) { 

        printf("Server terminated.\n"); 

        return; 

        } 

 

     recvline[numbytes]='\0';  

     printf("Server Message: %s\n",recvline); /* it prints server's 

welcome message  */  

 

     } 

  printf("\nExit.\n"); 

  }  

 

  char* getMessage(char* sendline,int len, FILE* fp)  

  { 

  printf("Input string to server:"); 

  return(fgets(sendline, MAXDATASIZE, fp)); 

  } 

/* server.c */ 

  #include <stdio.h>          /* These are the usual header files */  

  #include <strings.h>          /* for bzero() */ 

  #include <unistd.h>         /* for close() */ 

  #include <sys/types.h>  

  #include <sys/socket.h>  

  #include <netinet/in.h>  

  #include <arpa/inet.h> 

 

  #define PORT 1234   /* Port that will be opened */  

  #define BACKLOG 2   /* Number of allowed connections */  

  #define MAXDATASIZE 1000   

  void process_cli(int connectfd, struct sockaddr_in client); 

 

  main()  

  {  

  int listenfd, connectfd; /* socket descriptors */  

  pid_t pid; 

  struct sockaddr_in server; /* server's address information */  

  struct sockaddr_in client; /* client's address information */  

  int sin_size;  

 

  /* Create TCP socket  */ 

  if ((listenfd = socket(AF_INET, SOCK_STREAM, 0)) == -1) { 

     /* handle exception */ 

     perror("Creating socket failed."); 

     exit(1); 

     } 

 

  int opt = SO_REUSEADDR; 

  setsockopt(listenfd, SOL_SOCKET, SO_REUSEADDR, &opt, 

sizeof(opt)); 

   bzero(&server,sizeof(server)); 

  server.sin_family=AF_INET;  

  server.sin_port=htons(PORT);  

  server.sin_addr.s_addr = htonl (INADDR_ANY);  

  if (bind(listenfd, (struct sockaddr *)&server, sizeof(struct 

sockaddr)) == -1) {  

     /* handle exception */ 

     perror("Bind error."); 

     exit(1);  

     }     

 

  if(listen(listenfd,BACKLOG) == -1){  /* calls listen() */  

     perror("listen() error\n");  

     exit(1);  

     }  

 

  sin_size=sizeof(struct sockaddr_in);  

   while(1) 

  { 

     /*accept connection */ 

   if ((connectfd = accept(listenfd,(struct sockaddr 

*)&client,&sin_size))==-1) { 

     perror("accept() error\n");  

     exit(1);  

     }  

  /*  Create child process to service client */ 

  if ((pid=fork())>0) { 

     /* parent process */ 

     close(connectfd); 

     continue; 

     } 

  else if (pid==0) { 

     /*child process*/ 

     close(listenfd); 

     process_cli(connectfd, client); 

     exit(0);      

     } 

  else { 

     printf("fork error\n"); 

     exit(0); 

     } 

  } 

  close(listenfd);   /* close listenfd */          

  }  

 

  void process_cli(int connectfd, struct sockaddr_in client) 

  { 

  int num,i; 

  char recvbuf[MAXDATASIZE], sendbuf[MAXDATASIZE], 

cli_name[MAXDATASIZE]; 

 

  printf("You got a connection from %s.  

",inet_ntoa(client.sin_addr) ); /* prints client's IP */  

  /* Get client's name from client */ 

  num = recv(connectfd, cli_name, MAXDATASIZE,0); 

  if (num == 0) { 

     close(connectfd); 

     printf("Client disconnected.\n"); 

     return; 

     } 

  cli_name[num - 1] = '\0'; 

  printf("Client's name is %s.\n",cli_name); 

 

  while (num = recv(connectfd, recvbuf, MAXDATASIZE,0)) { 

     recvbuf[num] = '\0'; 

     printf("Received client( %s  ) message: %s",cli_name, recvbuf); 

     for ( i = 0; i < num - 1; i++) { 

        sendbuf[i] = recvbuf[num - i -2]; 

        } 

     sendbuf[num - 1] = '\0'; 

 

     send(connectfd,sendbuf,strlen(sendbuf),0); /* send to the 

client welcome message */  

     } 

  close(connectfd); /*  close connectfd */  

  }


运行结果:




//对上述的server程序进行修改(client保持不变),即可对实现“建立一数据文件(log.txt) ,用于记录各个客户机登录、传送信息等数据 ”


/* server.c */ 

  #include <stdio.h>          /* These are the usual header files */  

  #include <strings.h>          /* for bzero() */ 

  #include <unistd.h>         /* for close() */ 

  #include <sys/types.h>  

  #include <sys/socket.h>  

  #include <netinet/in.h>  

  #include <arpa/inet.h> 

 

  #define PORT 1234   /* Port that will be opened */  

  #define BACKLOG 2   /* Number of allowed connections */  

  #define MAXDATASIZE 1000   

  void process_cli(int connectfd, struct sockaddr_in client); 

int main()  

  {  

  int listenfd, connectfd; /* socket descriptors */  

  pid_t pid; 

  struct sockaddr_in server; /* server's address information */  

  struct sockaddr_in client; /* client's address information */  

  int sin_size;  

  /* Create TCP socket  */ 

  if ((listenfd = socket(AF_INET, SOCK_STREAM, 0)) == -1) { 

     /* handle exception */ 

     perror("Creating socket failed."); 

     exit(1); 

     } 

  int opt = SO_REUSEADDR; 

  setsockopt(listenfd, SOL_SOCKET, SO_REUSEADDR, &opt, sizeof(opt)); 

   bzero(&server,sizeof(server)); 

  server.sin_family=AF_INET;  

  server.sin_port=htons(PORT);  

  server.sin_addr.s_addr = htonl (INADDR_ANY);  

  if (bind(listenfd, (struct sockaddr *)&server, sizeof(struct 

sockaddr)) == -1) {  

     /* handle exception */ 

     perror("Bind error."); 

     exit(1);  

     }     

 

  if(listen(listenfd,BACKLOG) == -1){  /* calls listen() */  

     perror("listen() error\n");  

     exit(1);  

     }  

 

  sin_size=sizeof(struct sockaddr_in);  

   while(1) 

  { 

     /*accept connection */ 

   if ((connectfd = accept(listenfd,(struct sockaddr 

*)&client,&sin_size))==-1) { 

     perror("accept() error\n");  

     exit(1);  

     }  

  /*  Create child process to service client */ 

  if ((pid=fork())>0) { 

     /* parent process */ 

     close(connectfd); 

     continue; 

     } 

  else if (pid==0) { 

     /*child process*/ 

     close(listenfd); 

     process_cli(connectfd, client); 

     exit(0);      

     } 

  else { 

     printf("fork error\n"); 

     exit(0); 

     } 

  }

  close(listenfd);   /* close listenfd */          

  }  

 

  void process_cli(int connectfd, struct sockaddr_in client) 

  { 

  FILE *logfile;

  int num,i; 

  char recvbuf[MAXDATASIZE], sendbuf[MAXDATASIZE], cli_name[MAXDATASIZE]; 

  char ip[MAXDATASIZE];

  char *filename=".txt";

  char tmpname[MAXDATASIZE];

  sprintf(ip,"You got a connection from %s.  ",inet_ntoa(client.sin_addr) ); /* prints client's IP */  

  /* Get client's name from client */ 

 printf("%s",ip);

  num = recv(connectfd, cli_name, MAXDATASIZE,0); 

  if (num == 0) { 

     close(connectfd); 

     printf("Client disconnected.\n"); 

     return; 

     } 

   cli_name[num - 1] = '\0'; 

strncpy(tmpname,cli_name,strlen(cli_name));

strcat(tmpname,filename);

if((logfile=fopen(tmpname,"w"))==NULL)

{

  printf("error!");

  fclose(logfile);

  exit(0);

}

fputs(ip,logfile);

 printf("Client's name is %s.\n",cli_name); 

  while (num = recv(connectfd, recvbuf, MAXDATASIZE,0)) { 

     recvbuf[num] = '\0'; 

    fputs(recvbuf,logfile);

     printf("Received client( %s  ) message: %s",cli_name, recvbuf); 

     for ( i = 0; i < num - 1; i++) { 

        sendbuf[i] = recvbuf[num - i -2]; 

        } 

     sendbuf[num - 1] = '\0'; 

 

     send(connectfd,sendbuf,strlen(sendbuf),0); /* send to the 

client welcome message */  

     }

  fputs(recvbuf,logfile); 

  close(connectfd); /*  close connectfd */  

  fclose(logfile);

  } 

//运行结果



说明:该功能实现的主要思想,如果一个用户建立连接后,要输入用户名,这个时候利用用户名来建立一个以用户名为名的.txt文件,然后再进行写入数据。换句话就是用户的使用记录。






评论 2
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值