多线程服务器/客户机编程

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> 

 #include <pthread.h> 

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

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

  #define MAXDATASIZE 1000   

 

  void process_cli(int connectfd, struct sockaddr_in client); 

  /* function to be executed by the new thread */ 

  void* start_routine(void* arg); 

  struct  ARG  { 

     int connfd; 

     struct sockaddr_in client;   

 }; 

 

 main()  

 {  

  int listenfd, connectfd; /* socket descriptors */  

  pthread_t  thread; 

  struct ARG *arg; 

  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 thread*/ 

 

     arg = (struct ARG *)malloc(sizeof(struct ARG)); 

     arg->connfd = connectfd; 

     memcpy((void *)&arg->client, &client, sizeof(client)); 

 

     if (pthread_create(&thread, NULL, start_routine, (void*)arg)) 

        /* handle exception */ 

        perror("Pthread_create() error"); 

        exit(1); 

        } 

 } 

  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) );  

  /* 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); 

     } 

  close(connectfd); /*  close connectfd */  

 } 

  void* start_routine(void* arg) 

 { 

  struct ARG *info; 

  info = (struct ARG *)arg; 

 

  /* handle client’s requirement */ 

 process_cli(info->connfd, info->client); 

 

 free(arg); 

 pthread_exit(NULL); 

 }

//运行结果




//修改上述的服务器代码,使得能够完成如下的功能:客户机 A 和客户机B相互之间可以通过服务器传递文本信息,服务器则记录双方通信的日志,通过编译运行。

/* 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> 

 #include <pthread.h> 

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

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

  #define MAXDATASIZE 1000   

static int i=0; 

 void process_cli(int connectfd, struct sockaddr_in client); 

  /* function to be executed by the new thread */ 

  void* start_routine(void* arg); 

  struct  ARG  { 

     int connfd; 

     struct sockaddr_in client;   

 }; 

 

 main()  

 {  

  int listenfd, connectfd; /* socket descriptors */  

  pthread_t  thread; 

  struct ARG *arg; 

  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 thread*/ 

 

     arg = (struct ARG *)malloc(sizeof(struct ARG)); 

     arg->connfd = connectfd; 

     memcpy((void *)&arg->client, &client, sizeof(client)); 

 

     if (pthread_create(&thread, NULL, start_routine, (void*)arg)) 

        /* handle exception */ 

        perror("Pthread_create() error"); 

        exit(1); 

        } 

 } 

  close(listenfd);   /* close listenfd */          

 }  

 

  void process_cli(int connectfd, struct sockaddr_in client) 

 {

  FILE *readlog;

  FILE *writelog; 

 int num; 

  char recvbuf[MAXDATASIZE], sendbuf[MAXDATASIZE], 

cli_name[MAXDATASIZE]; 

 

  printf("You got a connection from %s.",inet_ntoa(client.sin_addr) );  

  /* 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)) { 

if(i!=0) 

if((readlog=fopen("log.txt","a+"))==NULL)

  {

   fclose(readlog);

   exit(0);

  }

 while((fgetc(readlog))!=EOF)

 fgets(sendbuf,1024,readlog);

 fclose(readlog);

}else

{

   sprintf(sendbuf," ");

}

i++;

send(connectfd,sendbuf,strlen(sendbuf),0);

     recvbuf[num] = '\0'; 

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

  if((writelog=fopen("log.txt","a+"))==NULL)

  {

   fclose(writelog);

   exit(0);

  } 

 fputs(recvbuf,writelog);

 fclose(writelog);

}

  close(connectfd); /*  close connectfd */  

 } 

  void* start_routine(void* arg) 

 { 

  struct ARG *info; 

  info = (struct ARG *)arg; 

 

  /* handle client’s requirement */ 

 process_cli(info->connfd, info->client); 

 

 free(arg); 

 pthread_exit(NULL); 

 } 

//clent.c

/* 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("friend say: %s\n",recvline); /* it prints server's 

welcome message  */  

 

     } 

  printf("\nExit.\n"); 

  }  

 

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

  { 

  printf("my say:"); 

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

  } 

 //运行结果





  • 0
    点赞
  • 1
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值