亚洲av成人无遮挡网站在线观看,少妇性bbb搡bbb爽爽爽,亚洲av日韩精品久久久久久,兔费看少妇性l交大片免费,无码少妇一区二区三区

  免費(fèi)注冊(cè) 查看新帖 |

Chinaunix

  平臺(tái) 論壇 博客 文庫
最近訪問板塊 發(fā)新帖
查看: 3162 | 回復(fù): 5
打印 上一主題 下一主題

IPv[46]簡(jiǎn)單TCP服務(wù)器客戶端[200行打造] [復(fù)制鏈接]

論壇徽章:
0
跳轉(zhuǎn)到指定樓層
1 [收藏(0)] [報(bào)告]
發(fā)表于 2007-01-30 07:02 |只看該作者 |倒序?yàn)g覽

  1. /**********************************************
  2. 作者:Minuit
  3. 時(shí)間:2007年01月30日 星期二 04時(shí)36分08秒
  4. 文件名:tcp6servcli.c
  5. 描述:tcp服務(wù)器客戶端
  6. **********************************************/
  7. #include<stdio.h>
  8. #include<stdlib.h>
  9. #include<unistd.h>
  10. #include<string.h>
  11. #include<errno.h>
  12. #include <sys/types.h>
  13. #include <sys/socket.h>
  14. #include <netdb.h>
  15. enum {
  16.         NETINIT_TCPSERV=1,  /*創(chuàng)建一個(gè)tcp已經(jīng)監(jiān)聽套接口服務(wù)器*/
  17.         NETINIT_TCPCLI,         /*創(chuàng)建一個(gè)tcp已經(jīng)連接套接口客戶端*/
  18.         NETINIT_TCPCLIBIND,  /*創(chuàng)建一個(gè)tcp已經(jīng)連接并且綁定本IP地址和端口的客戶端*/
  19.         NETINIT_UDPSERV,   /*創(chuàng)建一個(gè)udp已經(jīng)綁定套接口服務(wù)器*/
  20.         NETINIT_UDPCLI,    /*創(chuàng)建一個(gè)udp客戶端*/
  21.         NETINIT_UDPCLICONN,  /*創(chuàng)建一個(gè)udp并且已經(jīng)連接服務(wù)器套接口客戶端*/
  22.         NETINIT_BACKLOG=100  
  23. };
  24. /*
  25. netinit 所能干的事情就上面那幾種
  26. 第一個(gè)參數(shù)主機(jī)名或者ip地址(當(dāng)建服務(wù)器時(shí)此參數(shù)可為空默認(rèn)BING一個(gè)通配的ipv6地址)
  27. 第二個(gè)參數(shù)服務(wù)名在/etc/services或者端口號(hào)(不能為空)
  28. 第三,四參數(shù)就不用介紹了說說有什么用處當(dāng)建立服務(wù)器時(shí)他返回相關(guān)協(xié)議的地址長度和地址結(jié)構(gòu)兩個(gè)都可能為空
  29. 根據(jù)須要比如建一個(gè)服務(wù)器當(dāng)調(diào)用accept(2)的時(shí)候如果想返回客戶機(jī)的信息那就要用到第四個(gè)參數(shù)地址長度(注:accept后兩個(gè)參數(shù)是可選的)又比如客戶端想用sendto發(fā)送信息到服務(wù)器那就可能須要一個(gè)服務(wù)器的地址如果你填了第三個(gè)參數(shù)它就返回一個(gè)服器的地址結(jié)構(gòu)這個(gè)還是很智能的(^_^)當(dāng)然像udp服務(wù)器只有調(diào)用recvfrom或者recvmsg才須要第四個(gè)參數(shù),udp客戶端只用用sendto或者sendmsg時(shí)會(huì)用到第三個(gè)參數(shù)總之只要第三,四個(gè)參數(shù)不空它就會(huì)給你填上你想要的東西如果為空那就是你不想讓他返回什么(你也可以過后調(diào)用get[sock|peer]name系統(tǒng)調(diào)用獲取你想要的結(jié)構(gòu)信息)
  30. 第四個(gè)參數(shù)已經(jīng)說過了
  31. */
  32. int netinit(const char *host,const char *serv,struct sockaddr *addr,socklen_t *addrlen,int flags)
  33. {
  34.         struct addrinfo hist,*res,*save;   
  35.         int sockfd,on=1,errcode;
  36.         bzero(&hist,sizeof(struct addrinfo));
  37.         if(serv==NULL)
  38.                 return -1;
  39.         hist.ai_family=AF_UNSPEC;
  40.         switch(flags)
  41.           {
  42.                 case NETINIT_TCPSERV:
  43.                 case NETINIT_UDPSERV:
  44.                         hist.ai_flags=AI_PASSIVE;   /*如果是服務(wù)器的話就設(shè)置被動(dòng)模式*/
  45.                         break;
  46.                 case NETINIT_TCPCLI:
  47.                 case NETINIT_UDPCLI:
  48.                 case NETINIT_UDPCLICONN:
  49.                 case NETINIT_TCPCLIBIND:
  50.                         hist.ai_flags=AI_CANONNAME;  /*如果是客戶端那就addrinfo結(jié)構(gòu)組成的鏈表第一個(gè)結(jié)構(gòu)里面的一個(gè)成員被填充主機(jī)名*/
  51.                         break;
  52.                 default:
  53.                         errno=ENOTSUP;  /*不支持有時(shí)間把unix域加上*/
  54.                         return -1;
  55.           }
  56.         switch(flags)
  57.           {
  58.                 case NETINIT_TCPCLI:
  59.                 case NETINIT_TCPSERV:
  60.                 case NETINIT_TCPCLIBIND:
  61.                         hist.ai_socktype=SOCK_STREAM;  /*udp還是tcp*/
  62.                         break;
  63.                 case NETINIT_UDPSERV:
  64.                 case NETINIT_UDPCLI:
  65.                 case NETINIT_UDPCLICONN:
  66.                         hist.ai_socktype=SOCK_DGRAM;
  67.                         break;
  68.                 default:
  69.                         errno=ENOTSUP;
  70.                         return -1;
  71.           }
  72.         if((errcode=getaddrinfo(host,serv,&hist,&res))!=0)
  73.           {
  74.                 fprintf(stderr,"getaddrinfo:%s\n",gai_strerror(errcode));
  75.                 return -1;
  76.           }
  77.         save=res;  /*保存res待會(huì)好毀了它*/
  78.         do
  79.           {
  80.                /*創(chuàng)建套接口不管是服務(wù)器還是客戶端的共同點(diǎn)必須要做的*/
  81.                 if((sockfd=socket(res->ai_family,res->ai_socktype,res->ai_protocol))>0)
  82.                   {
  83.                         /*要綁定地址的者在這里做*/
  84.                         if(flags==NETINIT_TCPSERV||flags==NETINIT_TCPCLIBIND||flags==NETINIT_UDPSERV)
  85.                           {
  86.                                 if(flags!=NETINIT_TCPCLIBIND)
  87.                                         if(setsockopt(sockfd,SOL_SOCKET,SO_REUSEADDR,&on,sizeof(on))!=0)  /*給服務(wù)器設(shè)置端口重用*/
  88.                                                 return -1;
  89.                                 if(bind(sockfd,res->ai_addr,res->ai_addrlen)==0)
  90.                                         break;
  91.                           }
  92.                         else
  93.                           {
  94.                                /*要建連接的者在這里做*/
  95.                                 if(flags!=NETINIT_UDPCLI)
  96.                                   {
  97.                                         if(connect(sockfd,res->ai_addr,res->ai_addrlen)==0)
  98.                                                 break;
  99.                                   }
  100.                                 else
  101.                                         break;
  102.                           }/*如果成功建立套接口那就先出去不然等到鏈表里的結(jié)構(gòu)都試完了就出去*/
  103.                   }
  104.                 close(sockfd);  /*如果創(chuàng)建不成功的話先關(guān)閉再說再試下面一個(gè)結(jié)構(gòu)*/
  105.           } while((res=res->ai_next)!=NULL);  
  106.         if(res==NULL)  /*如果失敗了返回*/
  107.                 return -1;
  108.         if(addr!=NULL)  
  109.                 memcpy(addr,res->ai_addr,res->ai_addrlen);
  110.         if(addrlen!=NULL)
  111.                 *addrlen=res->ai_addrlen;
  112.         freeaddrinfo(save);  /*釋放addrinfo鏈表之前已經(jīng)保存了地址*/
  113.         if(flags!=NETINIT_TCPSERV)  /*如果是tcp服務(wù)器的話還有一點(diǎn)事沒做其它的返回*/
  114.                 return sockfd;
  115.         else
  116.                 if(listen(sockfd,NETINIT_BACKLOG)!=0)     /*監(jiān)聽套接口*/
  117.                         return -1;
  118.         return sockfd;
  119. }
  120. void usage(char *arg)
  121. {
  122.         fprintf(stderr,\
  123.                         "Usage:%s [-cs] [<ip or hostname>] <port or server>\n",\
  124.                         arg);
  125.         exit(-1);
  126. }
  127. int main(int argc,char **argv)
  128. {
  129.         struct sockaddr *addr;
  130.         socklen_t  addrlen;
  131.         int servfd,clifd,pid,c,mode=1;
  132.         opterr=0;
  133.         while((c=getopt(argc,argv,"cs"))!=EOF)
  134.           {
  135.                 switch(c)
  136.                   {
  137.                         case 'c':
  138.                                 mode=0;
  139.                                 break;
  140.                         case 's':
  141.                                 mode=1;
  142.                                 break;
  143.             default:
  144.                                 usage(argv[0]);
  145.                   }
  146.           }
  147.         if((addr=malloc(sizeof(struct sockaddr_in6)))==NULL)
  148.                 return -1;
  149.         c=argc-optind;
  150.         switch(c)
  151.           {
  152.                 case 1:
  153.                         if(!mode)
  154.                                 usage(argv[0]);
  155.                         servfd=netinit(NULL,argv[optind],addr,NULL,NETINIT_TCPSERV);
  156.                         break;
  157.                 case 2:
  158.                         servfd=netinit(argv[optind],argv[optind+1],addr,mode?NULL:&addrlen,mode?NETINIT_TCPSERV:NETINIT_TCPCLI);
  159.                         break;
  160.                 default:
  161.                         usage(argv[0]);
  162.           }
  163.         if(servfd==-1)
  164.                 usage(argv[0]);
  165.         if(mode)
  166.           {
  167.                 while(1)
  168.                   {
  169.                         if((clifd=accept(servfd,addr,&addrlen))<=0)
  170.                           {
  171.                                 fprintf(stderr,"accept:%s\n",strerror(errno));
  172.                                 return -1;
  173.                           }
  174.                         if((pid=fork())<0)
  175.                           {
  176.                                 fprintf(stderr,"fork:%s\n",strerror(errno));
  177.                                 return -1;
  178.                           }
  179.                         else if(pid==0)
  180.                           {
  181.                                 char buf[BUFSIZ];
  182.                                 int n;
  183.                                 while((n=read(clifd,buf,BUFSIZ))>0)
  184.                                         write(clifd,buf,n);
  185.                                 exit(0);
  186.                           }
  187.                         close(clifd);
  188.                   }
  189.           }
  190.         else
  191.           {
  192.                 int n;
  193.                 char buf[BUFSIZ];
  194.                 while(1)
  195.                   {
  196.                 if(n=read(STDIN_FILENO,buf,BUFSIZ))
  197.                   {
  198.                   if(write(servfd,buf,n)!=n)
  199.                                   break;
  200.                   }
  201.                 else
  202.                         break;
  203.                 if((n=read(servfd,buf,BUFSIZ))>0)
  204.                   {
  205.                          if(write(STDOUT_FILENO,buf,n)!=n)
  206.                                  break;
  207.                   }
  208.                 else
  209.                         break;
  210.                   }
  211.                 close(servfd);
  212.           }
  213.         return 0;
  214. }
復(fù)制代碼


看了一步一步網(wǎng)絡(luò)編程*不知道還有人愛好這個(gè)
就把我前幾個(gè)月寫的通用的網(wǎng)絡(luò)初始化函數(shù)截下來寫這個(gè)二百行的服務(wù)器+客戶端簡(jiǎn)單網(wǎng)絡(luò)程序
讓大家也偷偷懶寫ipv[46]服務(wù)器客戶端也就那兩下子而且主機(jī)名IP地址 服務(wù)端口都可以用
我就不試范怎么用(4點(diǎn)多鐘來的才寫了這么多注釋^_^!)
就說一下兩個(gè)命令行參數(shù)
-c  以客戶端起動(dòng)
-s  以服務(wù)器起動(dòng)
如果沒有選項(xiàng)的話那默認(rèn)就服務(wù)器
服務(wù)器還最少要一個(gè)參數(shù)那就是端口或者服務(wù)名如果兩個(gè)參數(shù)那就綁定第一個(gè)參數(shù)所指的ip地址
客戶端必須兩個(gè)參數(shù)并且-c選項(xiàng)不能少
就這么多了
如果有什么不足之處還請(qǐng)指出^_^

[ 本帖最后由 lovesaka 于 2007-1-30 07:13 編輯 ]

論壇徽章:
0
2 [報(bào)告]
發(fā)表于 2007-01-30 09:26 |只看該作者
謝謝LZ,學(xué)習(xí)哈

論壇徽章:
0
3 [報(bào)告]
發(fā)表于 2007-01-30 17:03 |只看該作者
這個(gè)通用的與協(xié)議無關(guān)函數(shù)不好用嗎
怎么沒大俠出來指點(diǎn)一下呀^_^!

論壇徽章:
0
4 [報(bào)告]
發(fā)表于 2007-01-30 19:29 |只看該作者
多謝lz共享,只是我的水平還沒有到那個(gè)指點(diǎn)的水平上 ~~
等以后進(jìn)步了再說吧,呵呵

論壇徽章:
0
5 [報(bào)告]
發(fā)表于 2007-02-03 02:08 |只看該作者
多謝兩位支持
看來這東西使用上還是有點(diǎn)麻煩
但是他確實(shí)可以去掉很多每次老是要寫的代碼,又是IPV4,IPV6都能用的麻煩也是值得的^_^

論壇徽章:
0
6 [報(bào)告]
發(fā)表于 2007-02-03 12:00 |只看該作者
支持
雖然沒看代碼
但感覺是非常實(shí)用的東西啊
收藏了將來沒準(zhǔn)能用上
您需要登錄后才可以回帖 登錄 | 注冊(cè)

本版積分規(guī)則 發(fā)表回復(fù)

  

北京盛拓優(yōu)訊信息技術(shù)有限公司. 版權(quán)所有 京ICP備16024965號(hào)-6 北京市公安局海淀分局網(wǎng)監(jiān)中心備案編號(hào):11010802020122 niuxiaotong@pcpop.com 17352615567
未成年舉報(bào)專區(qū)
中國互聯(lián)網(wǎng)協(xié)會(huì)會(huì)員  聯(lián)系我們:huangweiwei@itpub.net
感謝所有關(guān)心和支持過ChinaUnix的朋友們 轉(zhuǎn)載本站內(nèi)容請(qǐng)注明原作者名及出處

清除 Cookies - ChinaUnix - Archiver - WAP - TOP