当前位置: 技术问答>linux和unix
给个很简单的例子,socket的!
来源: 互联网 发布时间:2015-08-15
本文导语: 一个socket服务端,最好是守护进程那种,接到连接请求后派生一个子进程来处理该连接通讯。谢谢。 | int daemon_init() { char szcwd[MAX_PATH]={0}; pid_t pid; if((pid=fork())=2){ if(strcmp(argv[1],"debug")==0){ ...
一个socket服务端,最好是守护进程那种,接到连接请求后派生一个子进程来处理该连接通讯。谢谢。
|
int daemon_init()
{
char szcwd[MAX_PATH]={0};
pid_t pid;
if((pid=fork())=2){
if(strcmp(argv[1],"debug")==0){
_DEBUG_=ON;
}
}
(void) signal(SIGPIPE,SIG_IGN); // 忽略部分信号,增强健壮性
(void) signal(SIGHUP,SIG_IGN);
(void) signal(SIGINT,SIG_IGN);
if(_DEBUG_==OFF){
daemon_init();
fd_standout = open(ENV_STANDOUT,O_WRONLY|O_CREAT|O_APPEND);
fd_standerr = open(ENV_STANDERR,O_WRONLY|O_CREAT|O_APPEND);
close(1); // 关闭标准输出
dup(fd_standout); // 将标准输出重定向到该文件
close(2); // 关闭标准错误输出
dup(fd_standerr); // 将标准错误输出重定向到该文件
close(fd_standout); // 关闭原文件句柄
close(fd_standerr); // 关闭原文件句柄
close(0); //关闭标准输入
}
// else{
//// daemon_init();
// }
FMODE_SERVICE.StartMonitor();
int ret = serv_listen();
switch(ret){
case -1:
LOG(DEBUG,"本地监听失败");
break;
case -2:
LOG(DEBUG,"本地监听线程创建失败");
break;
case 0:
LOG(DEBUG,"本地监听程序安全退出.");
break;
}
return 0;
}
int //守护进程通过本地socket接收命令
serv_listen()
{
int sockfd,connfd;
socklen_t clilen;
struct sockaddr_un cliaddr,servaddr;
const char szpath[]="fmode_sockt";
sockfd=socket(AF_LOCAL,SOCK_STREAM,0);
if(sockfd==-1){
perror("创建socket失败");
return -1;
}
unlink(szpath);
bzero(&servaddr,sizeof(servaddr));
servaddr.sun_family=AF_LOCAL;
strncpy(servaddr.sun_path,szpath,sizeof(servaddr.sun_path)-1);
if(-1==bind(sockfd,(struct sockaddr*)&servaddr,SUN_LEN(&servaddr))){
perror("绑定socket失败");
return -1;
}
if(listen(sockfd,BACKLOG)==-1){
perror("listen failure");
return -1;
}
accept_thd((void*)&sockfd);
shutdown(sockfd,SHUT_RDWR);
return 0;
}
void
accept_thd(void* argv)
{
int sockfd=*(int*)argv;
int connfd;
socklen_t clilen;
struct sockaddr_un cliaddr;
int i=0;
while(1)
{
clilen = sizeof(cliaddr);
connfd = accept(sockfd,(struct sockaddr*)&cliaddr,&clilen);
request(connfd);
}
shutdown(connfd,SHUT_RDWR);
}
int
request(int connfd)
{
int n=0;
sThd_Ctxt thd_ctxt;
bzero(&thd_ctxt,sizeof(tagThd_Ctxt));
bzero(thd_ctxt.buf,sizeof(thd_ctxt.buf));
n=recv(connfd,thd_ctxt.buf,MAX_PARAM_LEN,0);
if(g_bIdle==false){//限制一次只能执行一条命令
echo_req(connfd,"系统正忙,请稍候再执行......n");
shutdown(connfd,SHUT_RDWR);
return 0;
}
if(n>0){
int rc;
pthread_t t;
thd_ctxt.fd = connfd;
rc =pthread_create(&t,NULL,doit_thd,(void*)&thd_ctxt);
}
else{
shutdown(connfd,SHUT_RDWR);
}
return 0;
}
void*
doit_thd(void* argv)
{
sThd_Ctxt *pthd_ctxt;
pthd_ctxt = (sThd_Ctxt*)argv;
pthread_detach(pthread_self());
if(doit(pthd_ctxt->fd,pthd_ctxt->buf)==-1){
LOG(DEBUG,"已经退出系统.");
exit(0);
}
}
{
char szcwd[MAX_PATH]={0};
pid_t pid;
if((pid=fork())=2){
if(strcmp(argv[1],"debug")==0){
_DEBUG_=ON;
}
}
(void) signal(SIGPIPE,SIG_IGN); // 忽略部分信号,增强健壮性
(void) signal(SIGHUP,SIG_IGN);
(void) signal(SIGINT,SIG_IGN);
if(_DEBUG_==OFF){
daemon_init();
fd_standout = open(ENV_STANDOUT,O_WRONLY|O_CREAT|O_APPEND);
fd_standerr = open(ENV_STANDERR,O_WRONLY|O_CREAT|O_APPEND);
close(1); // 关闭标准输出
dup(fd_standout); // 将标准输出重定向到该文件
close(2); // 关闭标准错误输出
dup(fd_standerr); // 将标准错误输出重定向到该文件
close(fd_standout); // 关闭原文件句柄
close(fd_standerr); // 关闭原文件句柄
close(0); //关闭标准输入
}
// else{
//// daemon_init();
// }
FMODE_SERVICE.StartMonitor();
int ret = serv_listen();
switch(ret){
case -1:
LOG(DEBUG,"本地监听失败");
break;
case -2:
LOG(DEBUG,"本地监听线程创建失败");
break;
case 0:
LOG(DEBUG,"本地监听程序安全退出.");
break;
}
return 0;
}
int //守护进程通过本地socket接收命令
serv_listen()
{
int sockfd,connfd;
socklen_t clilen;
struct sockaddr_un cliaddr,servaddr;
const char szpath[]="fmode_sockt";
sockfd=socket(AF_LOCAL,SOCK_STREAM,0);
if(sockfd==-1){
perror("创建socket失败");
return -1;
}
unlink(szpath);
bzero(&servaddr,sizeof(servaddr));
servaddr.sun_family=AF_LOCAL;
strncpy(servaddr.sun_path,szpath,sizeof(servaddr.sun_path)-1);
if(-1==bind(sockfd,(struct sockaddr*)&servaddr,SUN_LEN(&servaddr))){
perror("绑定socket失败");
return -1;
}
if(listen(sockfd,BACKLOG)==-1){
perror("listen failure");
return -1;
}
accept_thd((void*)&sockfd);
shutdown(sockfd,SHUT_RDWR);
return 0;
}
void
accept_thd(void* argv)
{
int sockfd=*(int*)argv;
int connfd;
socklen_t clilen;
struct sockaddr_un cliaddr;
int i=0;
while(1)
{
clilen = sizeof(cliaddr);
connfd = accept(sockfd,(struct sockaddr*)&cliaddr,&clilen);
request(connfd);
}
shutdown(connfd,SHUT_RDWR);
}
int
request(int connfd)
{
int n=0;
sThd_Ctxt thd_ctxt;
bzero(&thd_ctxt,sizeof(tagThd_Ctxt));
bzero(thd_ctxt.buf,sizeof(thd_ctxt.buf));
n=recv(connfd,thd_ctxt.buf,MAX_PARAM_LEN,0);
if(g_bIdle==false){//限制一次只能执行一条命令
echo_req(connfd,"系统正忙,请稍候再执行......n");
shutdown(connfd,SHUT_RDWR);
return 0;
}
if(n>0){
int rc;
pthread_t t;
thd_ctxt.fd = connfd;
rc =pthread_create(&t,NULL,doit_thd,(void*)&thd_ctxt);
}
else{
shutdown(connfd,SHUT_RDWR);
}
return 0;
}
void*
doit_thd(void* argv)
{
sThd_Ctxt *pthd_ctxt;
pthd_ctxt = (sThd_Ctxt*)argv;
pthread_detach(pthread_self());
if(doit(pthd_ctxt->fd,pthd_ctxt->buf)==-1){
LOG(DEBUG,"已经退出系统.");
exit(0);
}
}
|
参考UNIX NETWROKING PROGRAMMING