linux之TCP/IP创建线程实现简单聊天(2)

来源:互联网 发布:js取数组最后一个值 编辑:程序博客网 时间:2024/06/05 08:29

周末无聊,创建个多线程实现简单聊天功能,顺便温习下linux的TCP/IP。

下面贴代码大家一起学习!有些代码跟(1)篇重复,我就不注释了!

 

========tcp_server.c============

 

#include <stdio.h>#include <stdlib.h>#include <errno.h>#include <string.h>#include <netdb.h>#include <sys/types.h>#include <netinet/in.h>#include <sys/socket.h>#include <pthread.h>#define PORT 3333void *thrd_write(void *arg)        //写线程{ int sockfd=(int)arg;         //穿进来的客户端端口 char buf[100]; while(1) {    fgets(buf,100,stdin);            //从屏幕得到你输入的字符   if(write(sockfd,buf,sizeof(buf))<0)            //写功能  {   fprintf(stderr,"write Error:%s\a\n",strerror(errno));   exit(1);  }   }  pthread_exit(NULL);            //线程退出}int main(int argc, char *argv[]){ int sockfd; struct sockaddr_in server_addr; struct sockaddr_in client_addr; int sin_size;  char buf[100];  sockfd = socket(AF_INET,SOCK_STREAM,0); if(sockfd == -1) {  fprintf(stderr,"Socket error:%s\n",strerror(errno));  exit(1); }  bzero(&server_addr,sizeof(struct sockaddr_in)); server_addr.sin_family = AF_INET; server_addr.sin_addr.s_addr = htonl(INADDR_ANY); server_addr.sin_port = htons(PORT); int on=1; setsockopt(sockfd,SOL_SOCKET,SO_REUSEADDR,&on,sizeof(on));         //上次(1)篇没解释,其实这个就是阻止服务端一关掉,再启动,运行不了的情况发生 if(bind(sockfd,(struct sockaddr *)(&server_addr),sizeof(struct sockaddr_in))==-1)         {  fprintf(stderr,"Bind error:%s\n",strerror(errno));  exit(1); }   if(listen(sockfd,20)==-1) {                fprintf(stderr,"listen error:%s\n",strerror(errno));                exit(1); } int new_fd,res2; pid_t child; int r_size;  pthread_t thread_write;   //线程id,即线程标识符 while(1) {  printf("wait!!!!!\n");  memset(buf,0,100);  sin_size = sizeof(struct sockaddr_in);  if((new_fd=accept(sockfd,(struct sockaddr *)(&client_addr),&sin_size))==-1)  {                 fprintf(stderr,"Accept error:%s\n",strerror(errno));                 exit(1);  }  else  {   fprintf(stderr,"Server get connection from %s\n",inet_ntoa(client_addr.sin_addr));   res2=pthread_create(&thread_write,NULL,thrd_write,new_fd);       //创建线程   if(res2!=0)   {    perror("Pthread2 create fail");    exit(res2);   }   while(1)        //读取客户端信息   {    char buf[100];    int r_size;     if((r_size=read(new_fd,buf,100))==-1)     {     fprintf(stderr,"Read error:%s\n",strerror(errno));     exit(1);     }      printf("Server Received%d::%s\n",r_size,buf);   }     }       } close(sockfd); exit(0);} 

==========tcp_client.c=============== 

#include <stdlib.h>#include <stdio.h>#include <errno.h>#include <string.h>#include <netdb.h>#include <sys/types.h>#include <netinet/in.h>#include <sys/socket.h>#include <pthread.h>#define PORT 3333void *thrd_write(void *arg)       //同样创建个写线程{ int sockfd=(int)arg; char buf[100]; while(1) {    fgets(buf,100,stdin);  if(write(sockfd,buf,sizeof(buf))<0)  {   fprintf(stderr,"write Error:%s\a\n",strerror(errno));   exit(1);  } }  pthread_exit(NULL);}int main(int argc, char *argv[]){ int sockfd; char buf[100]; struct sockaddr_in server_addr; struct hostent *host;  sockfd = socket(AF_INET,SOCK_STREAM,0); if(sockfd==-1) {  fprintf(stderr,"Socket error:%s\n",strerror(errno));  exit(1);  } bzero(&server_addr,sizeof(server_addr)); server_addr.sin_family=AF_INET; server_addr.sin_port=htons(PORT); server_addr.sin_addr.s_addr=inet_addr("192.168.1.155"); int con_flag,res2; pthread_t thread_write;  con_flag=connect(sockfd,(struct sockaddr *)(&server_addr),sizeof(struct sockaddr));   //连接服务端 if(con_flag==-1) {  fprintf(stderr,"Connect Error:%s\a\n",strerror(errno));   exit(1);  } else {  res2=pthread_create(&thread_write,NULL,thrd_write,sockfd);     if(res2!=0)  {   perror("Pthread2 create fail");   exit(res2);  }  while(1)  //读服务端信息  {   char buf[100];   int r_size;    if((r_size=read(sockfd,buf,100))==-1)    {    fprintf(stderr,"Read error:%s\n",strerror(errno));    exit(1);    }     printf("Client Received%d::%s\n",r_size,buf);  } } void *thrd_ret1; pthread_join(thread_read,&thrd_ret1);  //线程阻塞等待结束  close(sockfd); return 0;}


 

程序运行结果如下:

root@wyz-vlinux:~/test# ./tcp_server
wait!!!!!
Server get connection from 192.168.1.155
Server Received100::hello server

hello client
Server Received100::nice to meet you!

Nice to meet you,too!

 

root@wyz-vlinux:~/test# ./tcp_client
hello server
Client Received100::hello client

nice to meet you!
Client Received100::Nice to meet you,too!