长风破浪会有时,直挂云帆济沧海

Dream Word

博客园 首页 新随笔 联系 订阅 管理
  • read,write与recv,send
  • readline实现
  • 用readline实现回射客户、服务器
  • getsockname ,getpeername
  • gethostname,gethostbyname,gethostbyaddr
  1. 基于readline的回射客户/服务器
    1. 服务端
      1.   
          1 #include <stdio.h>
          2 #include <errno.h>
          3 #include <string.h>
          4 #include <stdlib.h>
          5 #include <unistd.h>
          6 #include <sys/types.h>
          7 #include <sys/socket.h>
          8 #include <netinet/in.h>
          9 #include <arpa/inet.h>
         10 
         11 #define ERR_EXIT(m)\
         12     do{\
         13         perror(m);\
         14         exit(EXIT_FAILURE);\
         15     }while(0)
         16 
         17 
         18 ssize_t readn(int fd, void* buf,size_t count)
         19 {
         20     size_t nleft = count;
         21     ssize_t nread;
         22     char *bufp = (char*)buf;
         23     
         24     while(nleft > 0)
         25     {
         26         if((nread = read(fd,bufp,nleft)) < 0)
         27         {
         28             if(errno == EINTR)
         29                 continue;
         30             return -1;
         31         }
         32         else if(nread == 0)
         33         {
         34             return count-nleft;
         35         }
         36         
         37         bufp += nread;
         38         nleft -= nread;
         39     }
         40     return count;
         41 }
         42 
         43 ssize_t writen(int fd, void* buf,size_t count)
         44 {
         45     size_t nleft = count;
         46     ssize_t nwrite;
         47     char *bufp = (char*)buf;
         48     
         49     while(nleft > 0)
         50     {
         51         if((nwrite = write(fd,bufp,nleft)) < 0)
         52         {
         53             if (errno = EINTR)
         54                 continue;
         55             return -1;
         56         }
         57         else if(nwrite == 0)
         58             continue;
         59         bufp += nwrite;
         60         nleft -= nwrite;
         61     }    
         62     return count;
         63 }
         64 
         65 ssize_t recv_peek(int fd, void* buf,size_t count)
         66 {
         67     while(1)
         68     {
         69         int ret = recv(fd,buf,count,MSG_PEEK);
         70         if(ret == -1 && errno == EINTR)
         71             continue;
         72         return ret;
         73     }
         74 }
         75 
         76 ssize_t readline(int sockfd,void *buf,size_t maxline)
         77 {
         78     int ret;
         79     int nread;
         80     char *bufp= buf;
         81     int nleft =maxline;
         82     while(1)
         83     {
         84         ret = recv_peek(sockfd,bufp,nleft);
         85         if(ret < 0)
         86             return ret;
         87         else if(ret == 0)
         88             return ret;
         89         nread = ret;
         90         int i;
         91         for(i = 0; i < nread; i++)
         92         {
         93             if(bufp[i] == '\n')
         94             {
         95                 ret = readn(sockfd,bufp, i+1);
         96                 if(ret != i+1)
         97                     exit(EXIT_FAILURE);
         98                 return ret;
         99             }
        100         }
        101         if(nread > nleft)
        102             exit(EXIT_FAILURE);
        103         nleft -= nread;
        104         ret = readn(sockfd,bufp,nread);
        105         if(ret != nread)
        106             exit(EXIT_FAILURE);
        107         bufp += nread;
        108     } 
        109     return -1;
        110 }
        111 
        112 void do_service(int conn)
        113 {
        114     char recvbuf[1024];
        115     int n;
        116     while(1)
        117     {
        118         memset(recvbuf,0,sizeof(recvbuf));
        119         int ret = readline(conn,recvbuf,1024);
        120         if(ret == -1)
        121             ERR_EXIT("read");
        122         if(ret == 0)
        123         {
        124             printf("clien close");
        125             break;
        126         }
        127                 
        128         fputs(recvbuf,stdout);
        129         writen(conn,recvbuf,strlen(recvbuf));
        130     }
        131 }
        132 
        133 int main(void)
        134 {
        135     int listenfd;
        136     if((listenfd = socket(AF_INET,SOCK_STREAM,0)) < 0)
        137         ERR_EXIT("socket");
        138 
        139     struct sockaddr_in servaddr;
        140     memset(&servaddr, 0, sizeof(servaddr));
        141     servaddr.sin_family = AF_INET;
        142     servaddr.sin_port = htons(5188);
        143     servaddr.sin_addr.s_addr = htonl(INADDR_ANY);
        144 
        145     int on;
        146     if(setsockopt(listenfd, SOL_SOCKET, SO_REUSEADDR, &on, sizeof(on)) < 0)
        147         ERR_EXIT("setsockopt");
        148     if(bind(listenfd,(struct sockaddr*)&servaddr,sizeof(servaddr)) < 0)
        149         ERR_EXIT("bind");
        150     if(listen(listenfd,SOMAXCONN) < 0)
        151         ERR_EXIT("listen");
        152     struct sockaddr_in peeraddr;
        153     socklen_t peerlen = sizeof(peeraddr);
        154     int conn;
        155 
        156     pid_t pid;
        157     while(1)
        158     {
        159         if((conn = accept(listenfd,(struct sockaddr*)&peeraddr,&peerlen)) < 0)
        160             ERR_EXIT("accept");
        161         printf("ip=%s,port=%d\t\n",inet_ntoa(peeraddr.sin_addr),ntohs(peeraddr.sin_port));
        162 
        163         pid = fork();
        164         if(pid == -1)
        165             ERR_EXIT("fork");
        166         if(pid == 0)
        167         {
        168             close(listenfd);
        169             do_service(conn);
        170             exit(EXIT_SUCCESS);
        171         }
        172         else
        173             close(conn);
        174     }
        175     return 0;    
        176 }
        View Code

         

    2. 客户端
      1.   1 #include <stdio.h>
          2 #include <errno.h>
          3 #include <string.h>
          4 #include <stdlib.h>
          5 #include <unistd.h>
          6 #include <sys/types.h>
          7 #include <sys/socket.h>
          8 #include <netinet/in.h>
          9 #include <arpa/inet.h>
         10 
         11 #define ERR_EXIT(m)\
         12     do{\
         13         perror(m);\
         14         exit(EXIT_FAILURE);\
         15     }while(0)
         16 
         17 ssize_t readn(int fd, void* buf,size_t count)
         18 {
         19     size_t nleft = count;
         20     ssize_t nread;
         21     char *bufp = (char*)buf;
         22     
         23     while(nleft > 0)
         24     {
         25         if((nread = read(fd,bufp,nleft)) < 0)
         26         {
         27             if(errno == EINTR)
         28                 continue;
         29             return -1;
         30         }
         31         else if(nread == 0)
         32         {
         33             return count-nleft;
         34         }
         35         
         36         bufp += nread;
         37         nleft -= nread;
         38     }
         39     return count;
         40 }
         41 
         42 ssize_t writen(int fd, void* buf,size_t count)
         43 {
         44     size_t nleft = count;
         45     ssize_t nwrite;
         46     char *bufp = (char*)buf;
         47     
         48     while(nleft > 0)
         49     {
         50         if((nwrite = write(fd,bufp,nleft)) < 0)
         51         {
         52             if (errno = EINTR)
         53                 continue;
         54             return -1;
         55         }
         56         else if(nwrite == 0)
         57             continue;
         58         bufp += nwrite;
         59         nleft -= nwrite;
         60     }    
         61     return count;
         62 }
         63 
         64 size_t recv_peek(int fd, void* buf,size_t count)
         65 {
         66         while(1)
         67         {
         68                 int ret = recv(fd,buf,count,MSG_PEEK);
         69                 if(ret == -1 && errno == EINTR)
         70                         continue;
         71                 return ret;
         72         }
         73 }
         74 
         75 ssize_t readline(int sockfd,void *buf,size_t maxline)
         76 {
         77         int ret;
         78         int nread;
         79         char *bufp= buf;
         80         int nleft =maxline;
         81         while(1)
         82         {
         83                 ret = recv_peek(sockfd,bufp,nleft);
         84                 if(ret < 0)
         85                         return ret;
         86                 else if(ret == 0)
         87                         return ret;
         88                 nread = ret;
         89                 int i;
         90                 for(i = 0; i < nread; i++)
         91                 {
         92                         if(bufp[i] == '\n')
         93                         {   
         94                                 ret = readn(sockfd,bufp, i+1);
         95                                 if(ret != i+1)
         96                                         exit(EXIT_FAILURE);
         97                                 return ret;
         98                         }
         99                 }   
        100                 if(nread > nleft)
        101                         exit(EXIT_FAILURE);
        102                 nleft -= nread;
        103                 ret = readn(sockfd,bufp,nread);
        104                 if(ret != nread)
        105                         exit(EXIT_FAILURE);
        106                 bufp += nread;
        107         }
        108         return -1; 
        109 }
        110 
        111 int main(void)
        112 {
        113     int sock;
        114     if((sock= socket(AF_INET,SOCK_STREAM,0)) < 0)
        115         ERR_EXIT("socket");
        116 
        117     struct sockaddr_in servaddr;
        118     memset(&servaddr, 0, sizeof(servaddr));
        119     servaddr.sin_family = AF_INET;
        120     servaddr.sin_port = htons(5188);
        121     servaddr.sin_addr.s_addr = inet_addr("127.0.0.1");
        122 
        123     if(connect(sock,(struct sockaddr*)&servaddr, sizeof(servaddr)) < 0)
        124         ERR_EXIT("connect");
        125 
        126     struct sockaddr_in localaddr;
        127     socklen_t addrlen = sizeof(localaddr);
        128     if(getsockname(sock,(struct sockaddr*)&localaddr,&addrlen) < 0)
        129         ERR_EXIT("getsockname");
        130     printf("ip=%s,port=%d\t\n",inet_ntoa(localaddr.sin_addr),ntohs(localaddr.sin_port));
        131     char sendbuf[1024] = { 0 };
        132     char recvbuf[1024] = { 0 };
        133     int n;
        134     while(fgets(sendbuf,sizeof(sendbuf),stdin) != NULL)
        135     {
        136         writen(sock,sendbuf,strlen(sendbuf));
        137         int ret = readline(sock,recvbuf,sizeof(sendbuf));
        138         if(ret == -1)
        139             ERR_EXIT("readn");
        140         else if(ret ==  0)
        141         {
        142             printf("client close");
        143             break;
        144         }
        145         
        146         fputs(recvbuf,stdout);
        147 //        fputs(recvbuf,stdout);
        148 
        149         memset(sendbuf,0, sizeof(sendbuf));
        150         memset(recvbuf,0, sizeof(recvbuf));
        151     }
        152     close(sock);
        153     return 0;    
        154 }
        View Code

         

  2. gethostname

    

 1 #include <stdio.h>
 2 #include <errno.h>
 3 #include <string.h>
 4 #include <stdlib.h>
 5 #include <unistd.h>
 6 #include <sys/types.h>
 7 #include <sys/socket.h>
 8 #include <netinet/in.h>
 9 #include <arpa/inet.h>
10 #include <netdb.h>
11 
12 #define ERR_EXIT(m)\
13     do{\
14         perror(m);\
15         exit(EXIT_FAILURE);\
16     }while(0)
17 
18 int getlocalip(char *ip)
19 {
20     char host[100] = { 0 };
21     if(gethostname(host,sizeof(host)) < 0)
22         return -1;
23 
24     struct hostent *hp;
25         if((hp = gethostbyname(host)) == NULL)
26         return -1;
27 
28     strcpy(ip,inet_ntoa(*(struct in_addr*)hp->h_addr_list[0]));
29     return 0;
30 }
31 
32 int main()
33 {
34     char host[100] = { 0 };
35     if(gethostname(host,sizeof(host)) < 0)
36         ERR_EXIT("gethostname");
37     
38     struct hostent *hp;
39     if((hp = gethostbyname(host)) == NULL)
40         ERR_EXIT("gethostbyname");
41     
42     int i = 0;
43     while(hp->h_addr_list[i] != NULL)
44     {
45         printf("%s\n",inet_ntoa(*(struct in_addr*)hp->h_addr_list[i]));
46         i++;
47     }
48     char ip[16] = { 0 };
49     getlocalip(ip);
50     printf("localip=%s\n",ip);
51     return 0;
52 }
View Code

 

posted on 2018-04-27 16:36  长风II  阅读(133)  评论(0编辑  收藏  举报