多线程编程以及socket编程_Linux程序设计4chapter15

                   printf("listen failedn");

                   fprintf(stderr,"Please enter the server's hostname!n");

                   res = send(client_sock,buff,102,0);                  

                   }

                   re = pthread_create(&a_thread,NULL,thread1,(void*)client_sockfd);    

#include <string.h>

                   client_sockfd = accept(server_sockfd,(struct sockaddr *)&client_address,&client_len);

         sockfd = *((int *)arg);

         printf("exiting threadn");

#include <sys/socket.h>

#include <sys/socket.h>

         pthread_create(&id1,NULL,(void *) pthread_recv,(void*)&client_fd);

#include <unistd.h>

                                     break;

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

         pthread_join(id1,NULL);

                   res = send(sockfd,&ch,1,0);

客户端也创建两个线程:一个用于接收服务器端发送过来的信息;一个用来给服务器端发送信息。

 

2、 示例代码

针对这个现象我做了一些测试。1、把客户端改为只收,服务端改为只发。

}

                            close(sockfd);

 

         int len,i,res;                             //一个终端运行./client2  另外一个终端

                            buf[recvbytes]=0;

{

                   }

#include <stdlib.h>

         }                   

 

         if((client_fd=accept(sockfd,(struct sockaddr *)&client_sockaddr,&sin_size))==-1)

 

         }       

 

 

         int client_sock;

         int sockfd,client_fd,sin_size,ret;

         for(;;)                                                  

         sin_size =sizeof(struct sockaddr);

         int i,res;

perror("accept");

         server_address.sin_addr.s_addr = inet_addr("192.168.131.129");

void pthread_recv(void *arg);

                   memset(buff,0,102);

         close(sockfd);

         memset(buff,0,1024);

         }

         address.sin_addr.s_addr = inet_addr("192.168.131.129");

         }

         struct sockaddr_in address;                //运行  ./server2 就可以看到结果了

         pthread_join(id2,NULL);

void* thread1(void* arg)

 

 

         serv_addr.sin_port=htons(SERVPORT);

                            printf("recv error!res is %dn",res);            

                   {

                            break;

         close(sockfd);

                   char ch;

         int buf_len, client_fd,recvbytes;

                   }

         struct sockaddr_in server_sockaddr,client_sockaddr;

在对端崩溃之后,send出错只会返回-1,而recv出错有时返回-1,大多数时候返回0。只有在recv出错为0没有被捕获,而又继续send,才会导致进程立刻死亡(此时无法捕获send的错误)。

                   else

         int result;

         serv_addr.sin_family=AF_INET;

                   res = recv(client_sock,&ch,1,0);                     

         pthread_create(&id2,NULL,(void *) pthread_recv,(void*)&sockfd);

#include <sys/types.h>

         }

        

#define MAXDATASIZE 100

{

         printf("server send: ");

 

                   {

         }

{

         close(client_sock);

     {

         result = bind(server_sockfd,(struct sockaddr*)&server_address,server_len);

                   }

                            printf("send error,res is %d,exiting programn",res);

         {

 

         if(ret != 0)

                            close(sockfd);

     //host->h_addr强制类型转换;建议直接使用下面的方法

解决办法是:

void pthread_recv(void *arg);

         struct sockaddr_in server_address;

服务器端的代码client.c

                   }

void pthread_recv(void *arg)

         //for(i=0;i<100;i++)

//客户端接收数据线程

         strncpy(buff,"this is server",14);

                   perror("listen");

         printf("exiting programn");

         printf("sockfd=%dn",sockfd);

                            printf("send error,res is %dn",res);

                   perror("Pthread_send creat");

         }

         if(ret != 0)

#include <pthread.h>

         struct sockaddr_in server_sockaddr;

         result = listen(server_sockfd,5);

     {

                   /**/

         char buf[MAXDATASIZE];

                   //ch++;

 

                   }

         pthread_t id1,id2;

         if(result!=0)

#include <netinet/in.h>

 

         bzero(&(serv_addr.sin_zero),8);

         return ((void*)0);

                            if(!strncmp(buf,"end",3))         //只比较字符串前三个字符

                   if(res==-1)

         }

                  

         {

         {

                   sleep(1);

         char buff[1024];

 

                   //res = read(client_sock,&ch,1);                         

void Pthread_send(void * arg);

                            //pthread_exit((void*)(-1));

         if(connect(sockfd,(struct sockaddr *)&serv_addr,sizeof(struct sockaddr))==-1)

         return 0;

         pthread_join(id1,NULL);

         i = 0;

         serv_addr.sin_addr.s_addr=inet_addr(argv[1]);   //"127.0.0.1");       Internet地址

         printf("before sending,buff is:%sn",buff);

         struct hostent *host;

                  

                exit(1);

                   //}

}

Client2.C程序:

                   {

                   //{                                                 

     //接受并保存客户端的信息

 

                   {

         result = connect(sockfd,(struct sockaddr*)&address,len);

         {       

服务端崩掉会导致客户端recv出错为0,但没有被捕获,使得客户端在收不到数据的情况下一直死循环。客户端没有阻塞,recv的返回值是0。)

                                     break;

         }

                   if((sendbytes = send(sockfd,buf,buf_len,0))==-1)

两端的程序增加捕获recv的出错为0的情况,具体代码是if((res==-1)||(res==0))。这样无论哪端崩掉,对端都能够捕获出错的情况,处理出错的情况,不会出现进程突然死亡现象。

void pthread_recv(void *arg)

        

         int sockfd,sin_size,ret;

#include <arpa/inet.h>

                   perror("socket");

                            close(client_sock);                              

#include <stdio.h>

         if(result!=0)

                   perror("pthread_recv creat");

        

                   if((recvbytes = recv(sockfd,buf,MAXDATASIZE,0))==-1)

                  

         if(ret != 0)

}

#define BACKLOG 10                 //请求队列中的最大请求数

 

     //接收服务端发来的信息

                   //write(client_sockfd,&ch,1);

void Pthread_send(void * arg)

服务端程序使用了一个sever_socket,并把这个socket与本机的ip和监听的端口进行绑定,并监听这个socket,accept远端来的连接。Accept成功一次就会获得一个client_socket。这时创建一个新线程,并把这个这个client_socket作为线程参数传给新线程。一个新线程服务一个远端连接,处理他们的数据传输请求(不断的收发数据,循环)。

                   exit(1);

#include <netinet/in.h>

#include <unistd.h>

#include <netinet/in.h>

#include <errno.h>

                   /**/

         printf("socket success!,sockfd=%dn",sockfd);

#include <arpa/inet.h>

         while(1)

                   exit(1);

                            exit(1);

         client_sock = (int)arg;     

         server_sockaddr.sin_port=htons(SERVPORT);

                  

服务器端创建两个线程:一个用于接收客户端发送过来的信息;一个用来给客户端发送信息。

         if(result == -1)

        

        

{

                            return(-1);

#include <sys/types.h>

 

         //bind用于本地IP地址和端口的绑定

 

#include <stdlib.h>

 

 

         len = sizeof(address);

         sockfd = *((int *)arg);

                   exit(1);

                   if(!strncmp(buf,"end",3))         //只比较字符串的前三个字符

                            //pthread_exit((void*)(-1));                       

http://blog.sina.com.cn/s/blog_87766e4a0100yp7a.html

#include <sys/socket.h>

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

看了Linux程序设计4中文版,学习了多线程编程和socket编程。本文的程序参考自Linux程序设计4的第15章。

                   }

         sockfd = socket(AF_INET,SOCK_STREAM,0);              //

                   exit(1);

                   }

}

2、把客户端改为只发,服务端只收。

1、 基于多线程实现一个服务器和一个客户端实现全双工通信

                  

         ret=pthread_create(&id1,NULL,(void *)Pthread_send,(void*)&sockfd);

                            printf("create thread failedn");                                 

                   perror("pthread_recv creat");

         }

                   if((recvbytes = recv(client_fd ,buf,MAXDATASIZE,0))==-1)

本文由金沙官网线上发布于操作系统,转载请注明出处:多线程编程以及socket编程_Linux程序设计4chapter15

您可能还会对下面的文章感兴趣: