基本线程数据TSD的应用(linux)

学校教材内容,大部分代码来自上面,给学习这门课的同学用用,服务器端接收的数据反转一下返回给客户端

  1. 服务器端
#include <pthread.h>
#include <unistd.h>
#include <stdio.h>
#include <sys/types.h>
#include <sys/socket.h>
#include <netinet/in.h>
#include <arpa/inet.h>
#include <netdb.h>
#define PORT 1234
#define BACKLOG 2
#define MAXCHARSIZE 1000
void process_client(int connectfd,struct sockaddr_in client);
void *start_routine(void *arg);
void savedata(char *recvbuf, int len, char *cli_data);
struct ARG{
int connfd;
struct sockaddr_in client;
};
struct ARG *arg;
int main(void)
{
    int                listenfd,connectfd;
    struct sockaddr_in server,client;
    int                sin_size;
    int                opt=SO_REUSEADDR;
    pthread_t          tid;
    sin_size=sizeof(struct sockaddr_in);
    if((listenfd=socket(AF_INET,SOCK_STREAM,0))==-1)
    {
      perror("Create socket failed.");
      exit(-1);
    }
    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)
    {
	    perror("Bind error.");
	    exit(-1);
    }
    if(listen(listenfd,BACKLOG)==-1)
    {
	    perror("listen error.";
	    exit(-1);
    }
    while(1)
      {
      if((connectfd=accept(listenfd,(struct sockaddr *) &client,&sin_size))==-1)
            {
	    perror("Accept error.");
	    exit(-1);
	    }
      arg=(struct ARG *)malloc(sizeof (struct ARG));
      arg -> connfd = connectfd;
      memcpy((void *)&arg -> client, &client, sizeof(client));

      if(pthread_create(&tid, NULL, start_routine, (void *)arg))
         {
      	    perror("Pthread_create  error.\n");
            exit(-1);
      	  }
      }
      close(listenfd);
    }
      static pthread_key_t key;
      static pthread_once_t once = PTHREAD_ONCE_INIT;
      struct DATA_THR {
      int index;
      };
   static void key_destroy(void *buf) {
      free(buf);
      }
   static void buffer_key_alloc() {
      pthread_key_create(&key, key_destroy);
      }

   void savedata(char *recvbuf, int len, char *cli_data) 
   {
      struct DATA_THR *data;
      pthread_once(&once, buffer_key_alloc);
      if ((data = (struct DATA_THR *)pthread_getspecific ( key )) == NULL) {
      data = (struct DATA_THR *) calloc (1, sizeof(struct DATA_THR));
      pthread_setspecific (key, data);
      data -> index = 0;
      }
      int i;
      for (i=0; i<len; i++)cli_data[data->index++] = recvbuf[i];
      cli_data[data->index] = '\0';
   }
void process_client(int connectfd,struct sockaddr_in client){
      char   recvbuf[MAXCHARSIZE];
      char   sendbuf[MAXCHARSIZE];
      char   client_name[MAXCHARSIZE];
      char   client_data[5000];
      int    recvlen,i; 
      printf("You get a connetion from %s\n",inet_ntoa(client.sin_addr));
      send(connectfd,"Welcome to my server.\n",22,0);      
      recvlen=recv(connectfd,client_name,MAXCHARSIZE,0);
      if(recvlen==0){
      	close(connectfd);
      	printf("Client disconnected.\n");
      	return;
       }
       else if(recvlen<0){
       	  close(connectfd);
      	  printf("Connect broked.\n");
      	  return;
          }
      client_name[recvlen]='\0';    
      printf("Client name is %s.\n",client_name);
      bzero(recvbuf,1000);
      while(recvlen=recv(connectfd,recvbuf,MAXCHARSIZE,0)){
          savedata(recvbuf,recvlen,client_data);
      	  recvbuf[recvlen]='\0';
      	  printf("Receive from client(%s)  message:%s\n",client_name,recvbuf);
          for(i=0;i<recvlen;i++)
	       sendbuf[i] = recvbuf[recvlen - i -1] ;
	  sendbuf[recvlen]='\0';
	  send(connectfd,sendbuf,strlen(sendbuf),0);
          bzero(recvbuf,1000);
      } /*while*/
      printf("Client:%s disconnected.User's data:%s  \n",client_name,client_data);
      close(connectfd);
    } 
void *start_routine(void *arg) {
      struct ARG *info;
      info = (struct ARG *)arg;
      process_client(info -> connfd, info -> client);
      free(arg);
      pthread_exit(NULL);
     }
  1. 客户端
#include <unistd.h>
#include <sys/socket.h>
#include <netinet/in.h>
#include <netdb.h>
#define PORT 1234
#define MAXDATASIZE 1000
int main(int argc,char * argv[])
{
    int   fd,numbytes;
    char  buf[MAXDATASIZE];
    struct hostent * he;
    struct sockaddr_in server;
    int    i=1;
    if(argc!=2)
    {
      printf("Usage: %s <IP address>  \n",argv[0]);
      exit(-1);
    }
    if((he=gethostbyname(argv[1]))==NULL){
	 perror("gethostbyname error.");
	 exit(-1);
    }
    if((fd=socket(AF_INET,SOCK_STREAM,0))==-1){
	 perror("Create socket failed");   
	 exit(1);
       }
     bzero(&server,sizeof(server));
     server.sin_family=AF_INET;
     server.sin_port=htons(PORT);
     server.sin_addr=*((struct in_addr *)he->h_addr);
     if(connect(fd,(struct sockaddr *)&server,sizeof(struct sockaddr))==-1)
     {
	    perror("Bind error.");
	    exit(1);
       }
      if((numbytes=recv(fd,buf,MAXDATASIZE,0))==-1)
      {
	    perror("recv error.");
	    exit(1);
       }
       buf[numbytes]='\0';
       printf("Server Message: %s\n",buf);
       printf("Input your name: ");
       scanf("%s",buf) ;
       if((numbytes=send(fd,buf,strlen(buf),0))==-1) 
        {
	    perror("Send error.");
	    exit(1);
        }
      bzero(buf,1000);
      while(i){          
        printf("Input your message(max: %d): ",MAXDATASIZE);
        scanf("%s",buf) ;
        if(strlen(buf)<1) i=0	;
        if((numbytes=send(fd,buf,strlen(buf),0))==-1) 
        {
	    perror("Send error.");
	    exit(1);
         }
         bzero(buf,1000);
        if((numbytes=recv(fd,buf,MAXDATASIZE,0))==-1)
        {
	   perror("read error.\n"); 
	   exit(1);
         } 
        buf[numbytes]='\0'; 
        printf("The convince of your message: %s\n",buf);
        printf("\n") ;
        bzero(buf,1000);
      } 
    close(fd);
}
  1. 运行结果
    服务器端:
    在这里插入图片描述
    客户端1:
    在这里插入图片描述
    客户端2:
    在这里插入图片描述
  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

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

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

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值