天天看点

Linux网络编程实例详解

#i nclude stdio.h 
     #i nclude stdlib.h 
     #i nclude errno.h 
     #i nclude string.h 
     #i nclude sys/types.h 
     #i nclude netinet/in.h 
     #i nclude sys/socket.h 
     #i nclude sys/wait.h 
     #define MYPORT 3490 /*服务器监听端口号 */ 
     #define BACKLOG 10 /* 最大同时连接请求数 */ 
     main() 
     { 
     intsock fd,new_fd; /* 监听socket: sock_fd,数据传输socket:new_fd*/ 
     struct sockaddr_in my_addr; /* 本机地址信息 */ 
     struct sockaddr_in their_addr;/* 客户地址信息 */ 
     int sin_size; 
     if ((sockfd = socket(AF_INET,SOCK_STREAM, 0)) == -1) { /*错误检测 */ 
     perror("socket");exit(1); } 
     my_addr.sin_family=AF_INET; 
     my_addr.sin_port=htons(MYPORT);
     my_addr.sin_addr.s_addr =INADDR_ANY; 
     bzero(&(my_addr.sin_zero),8);
     if (bind(sockfd, (structsockaddr *)&my_addr, sizeof(struct sockaddr))   
      == -1) {/*错误检测*/ 
     perror("bind");exit(1); } 
     if (listen(sockfd, BACKLOG) ==-1) {/*错误检测*/ 
     perror("listen");exit(1); } 
     while(1) { /* main accept()loop */ 
     sin_size = sizeof(structsockaddr_in); 
     if ((new_fd = accept(sockfd,(struct sockaddr *)&their_addr,   
     &sin_size)) == -1) { 
     perror("accept");continue; } 
     printf("server: gotconnection from %s",inet_ntoa(their_addr.sin_addr));
     if (!fork()) { /* 子进程代码段 */ 
     if (send(new_fd, "Hello,world!", 14, 0) == -1) 
     perror("send");close(new_fd); exit(0); } 
     close(new_fd); /* 父进程不再需要该socket */ 
     waitpid(-1,NULL,WNOHANG) > 0/*等待子进程结束,清除子进程所占用资源*/ 
     } 
     }      
#i ncludestdio.h 
     #i nclude stdlib.h 
     #i nclude errno.h 
     #i nclude string.h 
     #i nclude netdb.h 
     #i nclude sys/types.h 
     #i nclude netinet/in.h 
     #i nclude sys/socket.h 
     #define PORT 3490 
     #define MAXDATASIZE 100 /*每次最大数据传输量 */ 
     int main(int argc, char*argv[]) 
     { 
     int sockfd, numbytes; 
     char buf[MAXDATASIZE]; 
     struct hostent *he; 
     struct sockaddr_in their_addr; 
     if (argc != 2) { 
     fprintf(stderr,"usage:client hostname"); exit(1); } 
     if((he=gethostbyname(argv[1]))==NULL){ 
     herror("gethostbyname");exit(1); } 
     if ((sockfd = socket(AF_INET,SOCK_STREAM, 0)) == -1) { 
     perror("socket");exit(1); } 
     their_addr.sin_family=AF_INET; 
     their_addr.sin_port=htons(PORT);
     their_addr.sin_addr = *((structin_addr *)he->h_addr); 
     bzero(&(their_addr.sin_zero),8);
     if (connect(sockfd, (structsockaddr *)&their_addr,   
      sizeof(struct sockaddr)) ==-1) {/*错误检测*/ 
     perror("connect");exit(1); } 
     if ((numbytes=recv(sockfd, buf,MAXDATASIZE, 0)) == -1) { 
     perror("recv");exit(1); } 
     buf[numbytes] = ''; 
     printf("Received:%s",buf); 
     close(sockfd); 
     return 0; 
     }      
FD_ZERO(fd_set *set)----清除一个文件描述符集; 
     FD_SET(int fd,fd_set *set)----将一个文件描述符加入文件描述符集中; 
   
     FD_CLR(int fd,fd_set *set)----将一个文件描述符从文件描述符集中清除 
   ; 
     FD_ISSET(int fd,fd_set*set)----试判断是否文件描述符被置位。 
     Timeout参数是一个指向struct timeval类型的指针,它可以使select()在等待timeout长时间后没有文件描述符准备好即返回。struct timeval数据结构为: 
   
     struct timeval { 
      int tv_sec; /* seconds */ 
      int tv_usec; /* microseconds*/ 
     }; 
     我们通过程序3来说明: 
     #i nclude sys/time.h 
     #i nclude sys/types.h 
     #i nclude unistd.h 
     #define STDIN 0 /*标准输入文件描述符*/ 
     main() 
     { 
      struct timeval tv; 
      fd_set readfds; 
      tv.tv_sec = 2; 
      tv.tv_usec = 500000; 
      FD_ZERO(&readfds); 
      FD_SET(STDIN,&readfds); 
      /* 这里不关心写文件和异常处理文件描述符集合 */ 
      select(STDIN+1, &readfds, NULL, NULL, &tv); 
      if (FD_ISSET(STDIN, &readfds)) printf("Akey was pressed!"); 

      else printf("Timedout."); 
     } 
     (程序3) 
     select()在被监视端口等待2.5秒钟以后,就从select返回