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中,由客户端接收
到处,程序分析完结。
分析的过程也是自己学习的过程,难免有些错误,望大家指导
*********************************************************************************/
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中,由客户端接收
到处,程序分析完结。
分析的过程也是自己学习的过程,难免有些错误,望大家指导
相关阅读 更多 +