1. 程式人生 > >linux網路程式設計之用多執行緒實現客戶端到服務端的通訊(基於udp)

linux網路程式設計之用多執行緒實現客戶端到服務端的通訊(基於udp)

1、開啟一個執行緒接受資料,主執行緒傳送資料的程式碼

#include <unistd.h>
#include <stdio.h>
#include <stdlib.h>
#include <string.h>
#include <pthread.h>
#include <netinet/in.h>
#include <errno.h>
#include <sys/time.h>
#include <arpa/inet.h>
#include <sys/socket.h>
#include <sys/select.h>

//接收執行緒,負責訊息並且顯示
void *recv_thread(void* arg)
{
   int udp_fd = (int)arg;
   struct sockaddr_in addr;
   addr.sin_family = AF_INET;
   addr.sin_port = htons(8000);
   addr.sin_addr.s_addr = htonl(INADDR_ANY);

   socklen_t addrlen = sizeof(addr);
   bzero(&addr, sizeof(addr));
   while (1)
   {
       char buf[256] = "";
       char ipbuf[256] = "";
       recvfrom(udp_fd, buf, sizeof(buf), 0, (struct sockaddr*)&addr, &addrlen);
       printf("\r\033[0:31m[%s]:\033[31m%s\n", inet_ntop(AF_INET, &addr.sin_addr, ipbuf, sizeof(ipbuf)), buf);
       write(1, "chenyu:", 7);
   }
   return NULL;
}


int main() 
{
   char buf[100] = "";
   int udp_fd = 0;
   pthread_t tid;
   struct sockaddr_in addr;
   struct sockaddr_in cliaddr;
    
   //對套接字初始化
   bzero(&addr, sizeof(addr));
   addr.sin_family = AF_INET;
   addr.sin_port = htons(8000);
   addr.sin_addr.s_addr = htonl(INADDR_ANY);

   bzero(&cliaddr, sizeof(cliaddr));
   cliaddr.sin_family = AF_INET;
   cliaddr.sin_port = htons(8000);
     
   //建立套介面
   if ((udp_fd = socket(AF_INET, SOCK_DGRAM, 0)) < 0) 
   {
      perror("socket create failed\n");
      exit(EXIT_FAILURE);
   }   
   puts("socket create success");
   //設定埠
   if (bind(udp_fd, (struct sockaddr*)&addr, sizeof(addr)) < 0)
   {
       perror("bind fail\n");
       close(udp_fd);
       exit(EXIT_SUCCESS);
   }
   puts("bind success");
   puts("input:  \"192.168.221.x\" to send msg to body");
//  printf("\033[39m"); //設定字型顏
   //建立執行緒
   tid = pthread_create(&tid, NULL, recv_thread, (void *)udp_fd);   
   fflush(stdout);
   puts("create pthread success");  
   while (1)
   {
       puts("hello0");
       //主執行緒負責發訊息
       write(1, "chenyu send", 11); //1表示標誌輸
       fgets(buf, sizeof(buf), stdin);//等待輸入
       puts("hello");
//       buf[strlen(buf) - 1] = '\0';
       if (strncmp(buf, "chen", 4) == 0) 
       {
          puts("go in strncpm"); 
          char ipbuf[INET_ADDRSTRLEN] = "";
          inet_pton(AF_INET, buf + 6, &cliaddr.sin_addr); //給套接字地址再賦值
 	  puts("inet_pton go in");
          printf("connect %s successful!\n", inet_ntop(AF_INET, &cliaddr.sin_addr, ipbuf, sizeof(ipbuf)));       continue;       
       }  
       else if (strncmp(buf, "exit", 4) == 0)
       {
   	  close(udp_fd);
 	  exit(0);
       }
       sendto(udp_fd, buf ,strlen(buf), 0 , (struct sockaddr*)&cliaddr, sizeof(cliaddr));
   }
   return 0;
}

2、執行結果