文章详情

  • 游戏榜单
  • 软件榜单
关闭导航
热搜榜
热门下载
热门标签
php爱好者> php文档>servfox源码分析(六)

servfox源码分析(六)

时间:2010-09-17  来源:swinner1985

退出,进入grab函数,该函数不断采集图像,不难理解。这个是在线程中运行的,同时main函数中其他的也在运行,回到main中
*********************************************************************************/
 serv_sock = open_sock(serverport);
 signal(SIGPIPE, SIG_IGN); /* Ignore sigpipe */
sa.sa_handler = sigchld_handler;
 sigemptyset(&sa.sa_mask);
 sa.sa_flags = SA_RESTART;
 syslog(LOG_ERR,"Spcaserv Listening on Port  %d\n",serverport);
 printf("Waiting .... for connection. CTrl_c to stop !!!! \n"); 
*********************************************************************************/
进入open_sock,我们看看
int open_sock (int port)
{
  struct sockaddr_in servadr;
  int server_handle;
  int O_on = 1;
/* Create a new socket */
  if ((server_handle = socket (AF_INET, SOCK_STREAM, 0)) == -1)
    exit_fatal ("Error opening socket Abort !");
  if (setsockopt (server_handle, SOL_SOCKET, SO_REUSEADDR,
    &O_on, sizeof (int)) == -1)            ///* 允许重复使用本地地址与套接字进行绑定 */
    exit_fatal ("Setting reused address fail Abort !");
/* Now set the server address struct and bind socket to the port*/
  initaddr (&servadr,NULL, port);
  if (bind
      (server_handle, (struct sockaddr *) &servadr,
       sizeof (struct sockaddr)) == -1)   /*绑定函数bind()*/
    exit_fatal ("error bind socket");
/* Listen on the socket */ /*调用listen()函数,创建未处理请求的队列*/
  if (listen (server_handle, MAXCONNECT) == -1)
    exit_fatal ("Damned errors when listen Abort !");
  return server_handle;
}
*********************************************************************************/
网络编程地址相关数据结构,两结构是等效的
struct sockaddr
{
       unsigned short sa_family; /*地址族*/
       char sa_data[14]; /*14字节的协议地址,包含该socket的IP地址和端口号。*/
};
struct sockaddr_in
{
       short int sa_family; /*地址族*/
       unsigned short int sin_port; /*端口号*/
       struct in_addr sin_addr; /*IP地址*/
       unsigned char sin_zero[8]; /*填充0 以保持与struct sockaddr同样大小*/
};

socket():该函数用于建立一个socket连接,可指定socket类型等信息。在建立了socket连接之后,可对sockaddr或sockaddr_in结构进行初始化,以保存所建立的socket地址信息。
socket()函数语法要点
 
所需头文件 #include <sys/socket.h>   
函数原型 int socket(int family, int type, int protocol)   
函数传入值 family:
协议族 AF_INET:IPv4协议   
  AF_INET6:IPv6协议   
    AF_LOCAL:UNIX域协议   
    AF_ROUTE:路由套接字(socket)   
    AF_KEY:密钥套接字(socket)   
 type:
套接字类型 SOCK_STREAM:字节流套接字socket   
  SOCK_DGRAM:数据报套接字socket   
    SOCK_RAW:原始套接字socket   
 protoco:0(原始套接字除外)   
函数返回值 成功:非负套接字描述符   
 出错:-1 
对于已经建立的socket,setsockopt用法:
如果在已经处于 ESTABLISHED状态下的socket(一般由端口号和标志符区分)调用
 closesocket(一般不会立即关闭而经历TIME_WAIT的过程)后想继续重用该socket:
BOOL bReuseaddr=TRUE;
 setsockopt(s,SOL_SOCKET ,SO_REUSEADDR,(const char*)&bReuseaddr,sizeof(BOOL));
bind()函数语法要点
 
所需头文件 #include <sys/socket.h>   
函数原型 int bind(int sockfd, struct sockaddr *my_addr, int addrlen)   
函数传入值 socktd:套接字描述符   
 my_addr:本地地址   
  addrlen:地址长度   
函数返回值 成功:0   
 出错:-1 
初始化设置IP地址 initaddr (&servadr,NULL, port);回到main函数中
*********************************************************************************/
signal(SIGPIPE, SIG_IGN); 
/* Ignore sigpipe 当服务器close一个连接时,若client端接着发数据。根据TCP协议的规定,会收到一个RST响应,client再往这个服务器发送数据时,系统会发出一个SIGPIPE信号给进程,告诉进程这个连接已经断开了,不要再写了。
    根据信号的默认处理规则SIGPIPE信号的默认执行动作是terminate(终止、退出),所以client会退出。若不想客户端退出可以把SIGPIPE设为SIG_IGN
    如:    signal(SIGPIPE,SIG_IGN);*/
 sa.sa_handler = sigchld_handler;
 sigemptyset(&sa.sa_mask);
 sa.sa_flags = SA_RESTART; /* Ignore sigpipe */
 syslog(LOG_ERR,"Spcaserv Listening on Port  %d\n",serverport);
 printf("Waiting .... for connection. CTrl_c to stop !!!! \n"); 
  while (videoIn.signalquit)
    {
     sin_size = sizeof(struct sockaddr_in);
  if ((new_sock = accept(serv_sock, (struct sockaddr *)&their_addr, &sin_size)) == -1)
  {
   continue;  /*调用accept()函数,等待客户端的连接,客户端结构体赋值给their_addr*/
  }
 syslog(LOG_ERR,"Got connection from %s\n",inet_ntoa(their_addr.sin_addr));
 printf("Got connection from %s\n",inet_ntoa(their_addr.sin_addr));
 pthread_create(&server_th, NULL, (void *)service, &new_sock); /*创建线程 进入service运行*/
    }
  pthread_join (w1, NULL);
  close(serv_sock);
  close_v4l (&videoIn);
return 0;
}
*********************************************************************************/
  如参数结构sigaction定义如下  
 struct sigaction   
{   
void (*sa_handler) (int);   
sigset_t sa_mask;   
int sa_flags;   
void (*sa_restorer) (void);   
}

进入service函数,将new_sock的值传递给*ir,即为socket套接口
void
service (void *ir)
{
  int *id = (int*) ir;
  int frameout = 1;
  struct frame_t *headerframe;
  int ret;
  int sock;
  int ack = 0;
 unsigned char wakeup = 0;
 unsigned short bright;
 unsigned short contrast;
  struct client_t message;
  sock = *id;
 // if(debug) printf (" \n I am the server %d \n", *id);
 /* initialize video setting */
 bright = upbright(&videoIn);
 contrast = upcontrast(&videoIn);
 bright = downbright(&videoIn);
 contrast = downcontrast(&videoIn);
  for (;;)
    {  
      memset(&message,0,sizeof(struct client_t));
  ret = read(sock,(unsigned char*)&message,sizeof(struct client_t));
  //if(debug) printf("retour %s %d ret\n",message.message,ret);
  if (ret < 0) {
   if(debug) printf(" Client vaporished !! \n");
  break;
  }
  if (!ret) break;
  if(ret && (message.message[0] != 'O')) break;
 
  if (message.updobright){
   switch (message.updobright){
  case 1: bright = upbright(&videoIn);
  break;
  case 2: bright = downbright(&videoIn);
  break;
  }
  ack = 1;
  } else if (message.updocontrast){
   switch (message.updocontrast){
  case 1: contrast = upcontrast(&videoIn);
  break;
  case 2: contrast = downcontrast(&videoIn);
  break;
  }
  ack = 1;
 } else if (message.updoexposure){
   switch (message.updoexposure){
  case 1: spcaSetAutoExpo(&videoIn);
  break;
  case 2:;
  break;
  }
  ack = 1;
 } else if (message.updosize){ //compatibility FIX chg quality factor ATM
   switch (message.updosize){
  case 1: qualityUp(&videoIn);
  break;
  case 2: qualityDown(&videoIn);
  break;
  }
  ack = 1;
 } else if (message.fps){
   switch (message.fps){
  case 1: timeDown(&videoIn);
  break;
  case 2: timeUp(&videoIn);
  break;
  }
  ack = 1;
 } else if (message.sleepon){
  ack = 1;
  } else ack =0;
       while ((frameout == videoIn.frame_cour) && videoIn.signalquit) usleep(1000);
       if (videoIn.signalquit){
 videoIn.framelock[frameout]++;
      headerframe = (struct frame_t *) videoIn.ptframe[frameout];
 //headerframe->nbframe = framecount++;
 //if(debug) printf ("reader %d key %s width %d height %d times %dms size %d \n", sock,headerframe->header,
 //headerframe->w,headerframe->h,headerframe->deltatimes,headerframe->size);
   headerframe->acknowledge = ack;
   headerframe->bright = bright;
   headerframe->contrast = contrast;
   headerframe->wakeup = wakeup;
  ret = write_sock(sock, (unsigned char *)headerframe, sizeof(struct frame_t)) ;
 
  if(!wakeup) 
  ret = write_sock(sock,(unsigned char*)(videoIn.ptframe[frameout]+sizeof(struct frame_t)),headerframe->size);

 // ret = write_sock(sock,(unsigned char*)(videoIn.ptframe[frameout]+sizeof(struct frame_t)),headerframe->size);
 videoIn.framelock[frameout]--;
 frameout = (frameout+1)%4;    
      } else {
       if(debug) printf("reader %d going out \n",*id);
 break;
      }
    }
  close_sock(sock);
  pthread_exit(NULL);
}
*********************************************************************************/
read(sock,(unsigned char*)&message,sizeof(struct client_t));不断读取客户端对图像的设置并存入message中,用以判断对图像的设置显示,其中客户端的设置格式应与message类型相同
write_sock(sock,(unsigned char*)(videoIn.ptframe[frameout]+sizeof(struct frame_t)),headerframe->size);读取储存的图像数据发送到socket中,由客户端接收
到处,程序分析完结。
分析的过程也是自己学习的过程,难免有些错误,望大家指导
相关阅读 更多 +
排行榜 更多 +
辰域智控app

辰域智控app

系统工具 下载
网医联盟app

网医联盟app

运动健身 下载
汇丰汇选App

汇丰汇选App

金融理财 下载