Chinaunix首页 | 论坛 | 博客
  • 博客访问: 1790072
  • 博文数量: 297
  • 博客积分: 285
  • 博客等级: 二等列兵
  • 技术积分: 3006
  • 用 户 组: 普通用户
  • 注册时间: 2010-03-06 22:04
个人简介

Linuxer, ex IBMer. GNU https://hmchzb19.github.io/

文章分类

全部博文(297)

文章存档

2020年(11)

2019年(15)

2018年(43)

2017年(79)

2016年(79)

2015年(58)

2014年(1)

2013年(8)

2012年(3)

分类: C/C++

2015-10-09 16:36:55

痛苦的想死,太复杂了,还是记录几个简单的玩具代码吧,这些例子都出自head first c.

点击(此处)折叠或打开

  1. #include <apue.h>
  2. #include <sys/socket.h>
  3. #include <arpa/inet.h>

  4. int main(int argc, char*argv[])
  5. {
  6.     char *advice[]={
  7.         "Take smaller bites\r\n",
  8.         "Go for the tight jeans. No they do NOT make you look fat.\r\n",
  9.         "One word: inappropriate\r\n",
  10.         "Just for today, be honest. Tell your boss what you *really* think\r\n",
  11.         "You might want to rethink that haircut\r\n"
  12.     };
  13.     int listener_d=socket(PF_INET,SOCK_STREAM,0);
  14.     
  15.     if(argc!=2)
  16.     {
  17.         printf("%s <port>\n",argv[0]);
  18.         exit(1);
  19.         }

  20.     struct sockaddr_in name;
  21.     name.sin_family=PF_INET;
  22.     name.sin_addr.s_addr=htonl(INADDR_ANY);
  23.     name.sin_port=(in_port_t)htons(atoi(argv[1]));
  24.     
  25.     int reuse=1;
  26.     if(setsockopt(listener_d,SOL_SOCKET,SO_REUSEADDR,(char *)&reuse,sizeof(int))==-1)
  27.         fputs("setsockopt() error\n",stderr);


  28.     if(bind(listener_d,(struct sockaddr*)&name,sizeof(name))==-1)
  29.         fputs("bind() error\n",stderr);

  30.     listen(listener_d,10);
  31.     puts("Waiting for connection");

  32.     while(1){
  33.         struct sockaddr_storage client_addr;
  34.         unsigned int address_size=sizeof(client_addr);
  35.         int connect_d=accept(listener_d,(struct sockaddr*)&client_addr,&address_size);
  36.         char *msg=advice[rand() % 5];

  37.         send(connect_d,msg,strlen(msg),0);
  38.         close(connect_d);
  39.     }
  40.     return 0;
  41. }
第一个例子比较简单,第二个多几个自定义函数,加上了信号的处理。

点击(此处)折叠或打开

  1. #include <apue.h>
  2. #include <sys/socket.h>
  3. #include <arpa/inet.h>
  4. #include <errno.h>

  5. int listener_d;

  6. void handle_shutdonw(int sig);
  7. int catch_signal(int sig,void(*handler)(int));
  8. int open_listener_socket();
  9. void bind_to_port(int socket,int port);
  10. int say(int socket,char *s);
  11. void error(char *msg);
  12. int read_in(int socket,char *buf,int len);

  13. int read_in(int socket,char *buf,int len)
  14. {
  15.     char *s=buf;
  16.     int slen=len;
  17.     int c=recv(socket,s,slen,0);
  18.     while((c>0)&&(s[c-1]!='\n')){
  19.         s+=c;
  20.         slen-=c;
  21.         c=recv(socket,s,slen,0);
  22.         }
  23.     if(c<0) //incase there is an error
  24.         return c;
  25.     else if(c==0)
  26.         buf[0]='\0'; //nothing read,send back an empty string
  27.     else
  28.         s[c-1]='\0';
  29.     return len-slen;
  30.     }

  31. void handle_shutdown(int sig)
  32. {
  33.     if(listener_d)
  34.         close(listener_d);

  35.     fprintf(stderr,"Bye!\n");
  36.     exit(0);
  37. }

  38. int catch_signal(int sig,void(*handler)(int))
  39. {
  40.     struct sigaction action;
  41.     action.sa_handler=handler;
  42.     sigemptyset(&action.sa_mask);
  43.     action.sa_flags=0;
  44.     return sigaction(sig,&action,NULL);
  45. }

  46. int open_listener_socket()
  47. {
  48.     int s=socket(PF_INET,SOCK_STREAM,0);
  49.     if(s==-1)
  50.         error("can't not open socket");

  51.     return s;
  52.     }

  53. void bind_to_port(int socket,int port)
  54. {
  55.     struct sockaddr_in name;
  56.     name.sin_family=PF_INET;
  57.     name.sin_addr.s_addr=htonl(INADDR_ANY);
  58.     name.sin_port=(in_port_t)htons(port);
  59.     int reuse=1;
  60.     if(setsockopt(socket,SOL_SOCKET,SO_REUSEADDR,(char*)&reuse,sizeof(int))==-1)
  61.         error("can't set the reuse option on the socket");

  62.     int c=bind(socket,(struct sockaddr*)&name,sizeof(name));
  63.     if(c==-1){
  64.         error("Can't bind to socket");
  65.         }
  66.     }

  67. int say(int socket,char *s) //send a string to a client
  68. {
  69.     int result=send(socket,s,strlen(s),0);
  70.     if(result==-1)
  71.         fprintf(stderr,"%s: %s\n","Error talking to the client",strerror(errno));
  72.     return result;
  73.     }

  74. void error(char *msg)
  75. {
  76.     fprintf(stderr,"%s: %s\n",msg,strerror(errno));
  77.     exit(1);
  78.     }



  79. int main(int argc, char *argv[])
  80. {
  81.     if(argc!=2){
  82.         fprintf(stderr,"%s <port>",argv[0]);
  83.         exit(1);
  84.         }

  85.     if(catch_signal(SIGINT,handle_shutdown)==-1)
  86.         error("can't set the interrupt handler");
  87.     
  88.     listener_d=open_listener_socket();
  89.     int port=atoi(argv[1]);
  90.     bind_to_port(listener_d,port);
  91.     if(listen(listener_d,10)==01)
  92.         error("can't listen");

  93.     struct sockaddr_storage client_addr;
  94.     unsigned int address_size=sizeof(client_addr);
  95.     puts("Waiting for connection");
  96.     char buf[255];

  97.     while(1)
  98.     {
  99.         int connect_d=accept(listener_d,(struct sockaddr*)&client_addr,&address_size);
  100.         if(connect_d==-1)
  101.             error("Can't open secondary socket");

  102.         if(say(connect_d,"Internet Knock-Knock Protocol Server\r\nVersion 1.0\r\nKnock!Knock!\r\n>")!=-1)
  103.         {
  104.             read_in(connect_d,buf,sizeof(buf));

  105.             if(strncasecmp("Who's there?",buf,12))
  106.                 say(connect_d,"You should say 'Who's ther?'!");
  107.             else{
  108.                 if(say(connect_d,"Osca\r\n> ")!=-1){
  109.                     read_in(connect_d,buf,sizeof(buf));
  110.                     if(strncasecmp("Oscar who?",buf,10))
  111.                         say(connect_d,"You should say 'Oscar who?'!\r\n");
  112.                     else
  113.                         say(connect_d,"Oscar silly question,you get a silly answer\r\n");
  114.                         }
  115.                     }
  116.                 }
  117.             close(connect_d);
  118.             }
  119.         return 0;
  120.         }
第三个例子则增加了一个fork() 和wait() ,即多进程的模型。

点击(此处)折叠或打开

  1. #include <apue.h>
  2. #include <sys/socket.h>
  3. #include <arpa/inet.h>
  4. #include <errno.h>

  5. int listener_d;

  6. void handle_shutdonw(int sig);
  7. int catch_signal(int sig,void(*handler)(int));
  8. int open_listener_socket();
  9. void bind_to_port(int socket,int port);
  10. int say(int socket,char *s);
  11. void error(char *msg);
  12. int read_in(int socket,char *buf,int len);

  13. int read_in(int socket,char *buf,int len)
  14. {
  15.     char *s=buf;
  16.     int slen=len;
  17.     int c=recv(socket,s,slen,0);
  18.     while((c>0)&&(s[c-1]!='\n')){
  19.         s+=c;
  20.         slen-=c;
  21.         c=recv(socket,s,slen,0);
  22.     }
  23.     if(c<0) //incase there is an error
  24.         return c;
  25.     else if(c==0)
  26.         buf[0]='\0'; //nothing read,send back an empty string
  27.     else
  28.         s[c-1]='\0';
  29.     return len-slen;
  30. }

  31. void handle_shutdown(int sig)
  32. {
  33.     if(listener_d)
  34.         close(listener_d);

  35.     fprintf(stderr,"Bye!\n");
  36.     exit(0);
  37. }

  38. int catch_signal(int sig,void(*handler)(int))
  39. {
  40.     struct sigaction action;
  41.     action.sa_handler=handler;
  42.     sigemptyset(&action.sa_mask);
  43.     action.sa_flags=0;
  44.     return sigaction(sig,&action,NULL);
  45. }

  46. int open_listener_socket()
  47. {
  48.     int s=socket(PF_INET,SOCK_STREAM,0);
  49.     if(s==-1)
  50.         error("can't not open socket");

  51.     return s;
  52. }

  53. void bind_to_port(int socket,int port)
  54. {
  55.     struct sockaddr_in name;
  56.     name.sin_family=PF_INET;
  57.     name.sin_addr.s_addr=htonl(INADDR_ANY);
  58.     name.sin_port=(in_port_t)htons(port);
  59.     int reuse=1;
  60.     if(setsockopt(socket,SOL_SOCKET,SO_REUSEADDR,(char*)&reuse,sizeof(int))==-1)
  61.         error("can't set the reuse option on the socket");

  62.     int c=bind(socket,(struct sockaddr*)&name,sizeof(name));
  63.     if(c==-1){
  64.         error("Can't bind to socket");
  65.     }
  66. }

  67. int say(int socket,char *s) //send a string to a client
  68. {
  69.     int result=send(socket,s,strlen(s),0);
  70.     if(result==-1)
  71.         fprintf(stderr,"%s: %s\n","Error talking to the client",strerror(errno));
  72.     return result;
  73. }

  74. void error(char *msg)
  75. {
  76.     fprintf(stderr,"%s: %s\n",msg,strerror(errno));
  77.     exit(1);
  78. }



  79. int main(int argc, char *argv[])
  80. {
  81.     if(argc!=2){
  82.         fprintf(stderr,"%s <port>",argv[0]);
  83.         exit(1);
  84.     }

  85.     if(catch_signal(SIGINT,handle_shutdown)==-1)
  86.         error("can't set the interrupt handler");

  87.     listener_d=open_listener_socket();
  88.     int port=atoi(argv[1]);
  89.     bind_to_port(listener_d,port);
  90.     if(listen(listener_d,10)==01)
  91.         error("can't listen");

  92.     struct sockaddr_storage client_addr;
  93.     unsigned int address_size=sizeof(client_addr);
  94.     puts("Waiting for connection");
  95.     char buf[255];

  96.     while(1)
  97.     {
  98.         int connect_d=accept(listener_d,(struct sockaddr*)&client_addr,&address_size);
  99.         if(connect_d==-1)
  100.             error("Can't open secondary socket");

  101.         if(fork()==0){ //child process
  102.             close(listener_d);
  103.             if(say(connect_d,"Internet Knock-Knock Protocol Server\r\nVersion 1.0\r\nKnock!Knock!\r\n>")!=-1)
  104.             {
  105.                 read_in(connect_d,buf,sizeof(buf));

  106.                 if(strncasecmp("Who's there?",buf,12))
  107.                     say(connect_d,"You should say 'Who's ther?'!");
  108.                 else{
  109.                     if(say(connect_d,"Osca\r\n> ")!=-1){
  110.                         read_in(connect_d,buf,sizeof(buf));
  111.                         if(strncasecmp("Oscar who?",buf,10))
  112.                             say(connect_d,"You should say 'Oscar who?'!\r\n");
  113.                         else
  114.                             say(connect_d,"Oscar silly question,you get a silly answer\r\n");
  115.                     }
  116.                 }
  117.             }
  118.             close(connect_d);
  119.             exit(0);
  120.         }
  121.         //wait(NULL);
  122.         close(connect_d);
  123.     }
  124.     return 0;
  125. }
#wait(NULL)是我自己加上去的,为了不产生zombie进程。否者只有主进程退出,子进程才会被init进程发现。
倒是让我想起来以前用nagios,经常会有zombie 进程的产生,估计是主进程少了waitpid 或者wait。除非主进程退出,zombie进程才会被init回收。




阅读(1311) | 评论(0) | 转发(0) |
给主人留下些什么吧!~~