Unix Socket 小程序

这个例子写得不错,值得参考学习,经过小的修改,我在AIX 5.3上编译 通过,测试也基本达到预期,至于详细的理解,有待完善 ……

    1. struct sockaddr_in { 
    2.        short int sin_family;        /* 地址族 */ 
    3.   unsigned short int sin_port;/* 端口号 */ 
    4.   struct in_addr sin_addr;    /* IP地址 */ 
    5.   unsigned char sin_zero[8];  /*填充0以保持与struct sockaddr同样大小*/ 
    6. }; 
    7. bzero()或memset()函数将sockaddr_in 声明的结构置为零。
    8. 为了建立Socket,程序可以调用Socket函数,该函数返回一个类似于文件描述符的句柄。socket 函数原型为:  int socket(int domain, int type, int protocol); 
    9. domain指明所使用的协议族,通常为PF_INET,表示互联网协议族(TCP/IP协议族);type参数指定socket的类型:SOCK_STREAM 或SOCK_DGRAM,Socket接口还定义了原始Socket(SOCK_RAW),允许程序使用低层协议;protocol通常赋值"0"。Socket()调用返回一个整型socket描述符,你可以在后面的调用使用它。
    10. int bind(int sockfd,struct sockaddr *my_addr, int addrlen); 
    11. Sockfd是调用socket函数返回的socket描述符,my_addr是一个指向包含有本机IP地址及端口号等信息的sockaddr类型的指针;addrlen常被设置为sizeof(struct sockaddr)。
    12. 计算机数据存储有两种字节优先顺序:高位字节优先和低位字节优先。Internet上数据以高位字节优先顺序在网络上传输,所以对于在内部是以低位字节优先方式存储数据的机器,在Internet上传输数据时就需要进行转换,否则就会出现数据不一致。 
    13. 下面是几个字节顺序转换函数: 
    14. htonl():把32位值从主机字节序转换成网络字节序 
    15. htons():把16位值从主机字节序转换成网络字节序 
    16. ntohl():把32位值从网络字节序转换成主机字节序 
    17. ntohs():把16位值从网络字节序转换成主机字节序 
    18. accept()函数让服务器接收客户的连接请求。在建立好输入队列后,服务器就调用accept函数,然后 睡眠并等待客户的连接请求。 
    19. int accept(int sockfd, void *addr, int *addrlen); 
    20. sockfd是被监听的socket描述符,addr通常是一个指向sockaddr_in变量的指针,该变量用来存放提出连接请求服务的主机的信息(某台主机从某个端口发出该请求);addrten通常为一个指向值为sizeof(struct sockaddr_in)的整型指针变量。出现错误时accept函数返回-1并置相应的errno值。
    21. Send()函数原型为: 
    22. int send(int sockfd, const void *msg, int len, int flags); 
    23. Sockfd是你想用来传输数据的socket描述符;msg是一个指向要发送数据的指针;Len是以字节为单位的数据的长度;flags一般情况下置为0。
    24. recv()函数原型为: 
    25. int recv(int sockfd,void *buf,int len,unsigned int flags); 
    26. Sockfd是接受数据的socket描述符;buf 是存放接收数据的缓冲区;len是缓冲的长度。Flags也被置为0。Recv()返回实际上接收的字节数,当出现错误时,返回-1并置相应的errno值。
  1.             相关文章介绍 : http://fanqiang.chinaunix.net/a4/b7/20010626/150001679.html
  1.  /*
  2.   *   Sever code
  3.   */
  4. #include<stdio.h>
  5. #include<stdlib.h>
  6. #include<unistd.h>
  7. #include<sys/socket.h>
  8. #include<sys/wait.h>
  9. #include<arpa/inet.h>
  10. #include<netinet/in.h>
  11. #include<string.h>
  12. #define   PORT      9877
  13. #define   BUFLEN      1024
  14. #define   MAXLEN   128
  15. #define   BACKLOG     10
  16. void   getbuf(char   *buf,int   sockfd);
  17. void   reversebuf(char   *buf);
  18. int main(int  argc,char  *argv[])
  19. {
  20.   /*init serversockfd,clientsockfd;*/
  21.   int                     listenfd,connectfd;
  22.   int                     clientaddrlen;
  23.   int                     status;
  24.   struct   sockaddr_in    clientaddr,serveraddr; /*Gong setting*/
  25.   socklen_t               sin_size;
  26.   char                    buf[BUFLEN];
  27.   pid_t                   pid;
  28.   char  *welcome = "Connect to server successful. Welcome!!!/n";
  29.   
  30.   if((listenfd=socket(AF_INET,SOCK_STREAM,0)) < 0)
  31.   {
  32.     /*create socket if failure exit*/
  33.     perror("create socket error!");
  34.     exit(1);
  35.   }
  36.   /*init serveraddr*/
  37.   bzero(&serveraddr,sizeof(serveraddr));
  38.   serveraddr.sin_family=AF_INET;
  39.   serveraddr.sin_port=htons(PORT);
  40.   serveraddr.sin_addr.s_addr=htonl(INADDR_ANY);
  41.   /*bind port and serveraddr to listenfd*/
  42.   if(bind(listenfd,(struct sockaddr *)&serveraddr,sizeof(struct sockaddr))<0)
  43.   {
  44.     perror("bind port failure!");
  45.     exit(1);
  46.   }
  47.   if(listen(listenfd,BACKLOG) < 0)
  48.   {
  49.     perror("listen error");
  50.     exit(1);
  51.   }
  52.   for(;;)
  53.   {
  54.     /*clientaddrlen=sizeof(clientaddr);*//* Gong setting */
  55.     sin_size = sizeof(struct sockaddr_in);
  56.     if((connectfd=accept(listenfd,(struct sockaddr*)&clientaddr,&sin_size))<0)
  57.     {
  58.       perror("accept from client failure!");
  59.       exit(1);
  60.     }
  61.     printf("Received client: %s request/n",inet_ntoa(clientaddr.sin_addr));
  62.     if((pid=fork()) < 0)
  63.     {
  64.       perror("fork error");
  65.       exit(1);
  66.     }
  67.     else if(pid  == 0)
  68.     {
  69.       getbuf(buf,connectfd);
  70.       printf("Get client string : %s/n",buf);
  71.       if(send(connectfd,welcome,strlen(welcome),0) < 0)
  72.       {
  73.         perror("send welcome failure");
  74.         exit(1);
  75.       }
  76.       reversebuf(buf); /*reverse   buf*/
  77.       /*send reversed string to client*/
  78.       if(send(connectfd,buf,strlen(buf),0) < 0)
  79.       {
  80.         perror("send reversed string error");
  81.         exit(1);
  82.       }
  83.       close(connectfd);
  84.       exit(0);
  85.     }
  86.     close(connectfd);
  87.   } /** End for loop **/
  88.   close(connectfd);
  89.   close(listenfd);
  90.   exit(0);
  91. }/** End main function **/
  92.   /*
  93.    *  getbuf()
  94.    */
  95.   void getbuf(char *buf,int sockfd)
  96.   {
  97.     char    tempbuf[MAXLEN];
  98.     int     n;
  99.     int     i,index;
  100.     index = 0;
  101.     n     = 0;
  102.     /*while(   (n=recv(sockfd,tempbuf,MAXLEN,0))>0   )*/
  103.     if((n=recv(sockfd,tempbuf,MAXLEN,0)) > 0)
  104.     {    
  105.       for(i=0; i<n; i++)
  106.         buf[index++]=tempbuf[i];
  107.     }
  108.     buf[index]='/0';
  109.     if(n < 0)
  110.     {
  111.       perror("recv   error");
  112.       exit(1);
  113.     }
  114.   }
  115.   /*
  116.    * reversebuf()
  117.    */
  118.   void reversebuf(char *buf)
  119.   {
  120.     char  c;
  121.     int   i,len;
  122.     int   mid=(int)len/2;
  123.     len=strlen(buf);  
  124.     for(i=0; i<mid; i++)
  125.     {
  126.       c=buf[i];
  127.       buf[i]=buf[len-1-i];
  128.       buf[len-1-i]=c;
  129.     }
  130.   }
  131. /*
  132.  *   Client code
  133.  */
  134. #include<stdio.h>
  135. #include<stdlib.h>
  136. #include<unistd.h>
  137. #include<sys/socket.h>
  138. #include<arpa/inet.h>
  139. #include<netinet/in.h>
  140. #include<sys/types.h>
  141. #include<sys/stat.h>
  142. #include<string.h>
  143. #include<sys/time.h>
  144. #define   PORT      9877
  145. #define   BUFLEN      1024
  146. #define   MAXLEN   128
  147. #define   MAXSLEEP   128
  148. int   connect_retry(int sockfd,struct sockaddr *addr,socklen_t alen);
  149. void  printbuf(int sockfd);
  150. void  getbuf(int sockfd,char *buf);
  151. int main(int argc,char *argv[])
  152. {
  153.   int                 sockfd;
  154.   struct sockaddr_in  serveraddr;
  155.   int                 addrlen;
  156.   pid_t               pid;
  157.   char  *str = "Gong Yao"
  158.   /*char   buf[BUFLEN];*/
  159.   if(argc != 2)
  160.   {
  161.     printf(" Pls follow : clienttest  ipaddress/n");
  162.     exit(1);
  163.   }
  164.   if((sockfd=socket(AF_INET,SOCK_STREAM,0)) < 0)
  165.   {
  166.     perror("create  socket  error");
  167.     exit(1);
  168.   }
  169.   bzero(&serveraddr,sizeof(serveraddr));
  170.   serveraddr.sin_family=AF_INET;
  171.   serveraddr.sin_port=htons(PORT);
  172.   inet_pton(AF_INET,argv[1],&serveraddr.sin_addr);
  173.   addrlen=sizeof(struct sockaddr);
  174.   if(connect_retry(sockfd,(struct sockaddr *)&serveraddr,addrlen) < 0)
  175.   {
  176.     printf("connect to server error /n");
  177.     exit(1);
  178.   }
  179.   if(send(sockfd,str,strlen(str),0) < 0)
  180.   {
  181.     perror("send str to server error");
  182.     exit(1);
  183.   }
  184.   /*fflush(sockfd);*//*Gong setting*/
  185.   printbuf(sockfd);
  186.   close(sockfd);
  187.   exit(0);
  188. }/** End main function **/
  189. /*
  190.  *  connect_retry()
  191.  */
  192. int connect_retry(int sockfd,struct sockaddr *addr,socklen_t alen)
  193. {
  194.   int   nsec;
  195.   for(nsec=1; nsec<MAXSLEEP; nsec<<=1)
  196.   {
  197.     if(connect(sockfd,addr,alen) == 0)
  198.       return 0 ;
  199.     if(nsec<=MAXSLEEP/2)
  200.       sleep(nsec);
  201.   }
  202.   return (-1);
  203. }
  204. /*
  205.  *  printbuf()
  206.  */
  207. void printbuf(int sockfd)
  208. {
  209.   char                buf[BUFLEN];
  210.   fd_set              rfd;
  211.   struct   timeval    timeout;
  212.   timeout.tv_sec  = 10;
  213.   timeout.tv_usec = 0;
  214.   FD_ZERO(&rfd);
  215.   FD_SET(sockfd,&rfd);
  216.   switch(select(sockfd+1,&rfd,NULL,NULL,&timeout))
  217.   {
  218.     case -1:
  219.       perror("select   error");
  220.       exit(1);
  221.     case 0:
  222.       printf("receive   data   from   server   timeout");
  223.       break;
  224.     default:
  225.       getbuf(sockfd,buf);
  226.       printf("Get string from server : ");
  227.       printf("%s",buf);
  228.       break;
  229.   }
  230.   printf("/n");
  231. }
  232. /*
  233.  *  getbuf()
  234.  */
  235. void getbuf(int sockfd,char *buf)
  236. {
  237.   char    tempbuf[MAXLEN];
  238.   int     i,n,index;
  239.   n     =   0;
  240.   index =   0;
  241.   while((n=recv(sockfd,tempbuf,MAXLEN,0)) > 0)
  242.   {
  243.     for(i=0; i<n; i++)
  244.       buf[index++]=tempbuf[i];
  245.   }
  246.   buf[index]='/0';
  247.   if(n  < 0)
  248.   {
  249.     perror("recv data from server error");
  250.     exit(1);
  251.   }
  252. }
  253.  

  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值