otjl吧 关注:19贴子:808
  • 0回复贴,共1
#include <unistd.h>
#include <sys/types.h>
#include <sys/stat.h>
#include <fcntl.h>
#include <stdio.h>
#include <string.h>
#include <malloc.h>
#include <signal.h>
#include <stdlib.h>
#include <assert.h>
#include <stdarg.h>
#include <sys/ioctl.h>
#include <sys/socket.h>
#include <netinet/in.h>
#include <netinet/tcp.h>
#include <arpa/inet.h>
#include <netdb.h>
#include <syslog.h>
typedef unsigned int BOOL;
#define TRUE 1
#define FALSE 0
#define MAX_WORKER 1024 //最多允许的接入连接数
#define MAX_IP_ADDR_SIZE 16 //IP地址串最大长度
#define SANGFOR_DEBUG_SIGNO (SIGRTMIN + 6) //调试信号
#define RESET_SIGNO SIGRTMIN + 7 //重置信号
/**
* 消息块
*/
struct msgblock {
unsigned char hdrsize;
unsigned int msgsize; //消息体的长度,即存放在content里的数据长度
char content[0]; //存放接收到的消息体,长度可变
};
/**
* 接入客户端
*/
struct worker {
int fd; //接入客户端使用的套接字
unsigned int recvlen;
};
/**
* 实时调试信息输出
*/
static void rtdump(const char* fmt, ...);
//监听套接字
static int s_listen_fd;
//所有接入的客户端
static struct worker s_workers[MAX_WORKER];
//是否接到了调试信号
static BOOL debug_signo_activated = FALSE;
/**
* 关闭所有接入连接
*/
static void close_all_worker(void)
{
int i;
for (i = 0; i < MAX_WORKER; ++i) {
if (s_workers[i].fd >= 0)
close(s_workers[i].fd);
}
}
/**
* 关闭listen套接字
*/
static void close_listener(void)
{
if (s_listen_fd >= 0)
close(s_listen_fd);
s_listen_fd = -1;
}
/**
* 创建listen socket
* @param listen_addr 该listen socket绑定的地址
* @param listen_port 套接字监听端口
* @return >=0表示创建成功,返回值为创建成功的socket,否则表示失败
*/
int create_listener(char *listen_addr, short listen_port)
{
int val = 1;
int ret = 0;
struct sockaddr_in addr;
socklen_t len = sizeof(addr);
assert(listen_addr);
addr.sin_family = AF_INET;
addr.sin_addr.s_addr = inet_addr(listen_addr);
addr.sin_port = htons(listen_port);
s_listen_fd = socket(AF_INET, SOCK_STREAM, 0);
if (s_listen_fd == -1) {
rtdump("error: socket(AF_INET, SOCK_STREAM, 0) failed\n");
return -1;
}
// 设置地址复用
ret = setsockopt(s_listen_fd, SOL_SOCKET
, SO_REUSEADDR, (const char *)&val, sizeof(val));
if (ret < 0) {
rtdump("warning: setsockopt(%d, SO_REUSEADDR) failed\n", s_listen_fd);
}
// 绑定地址
ret = bind(s_listen_fd, (struct sockaddr *)&addr, len);
if (ret < 0) {
rtdump("bind(%s:%d) failed\n", listen_addr, listen_port);
goto failed;
}
// 开始侦听
ret = listen(s_listen_fd, 5);
if (ret < 0) {
rtdump("socket[%d] listen failed\n", s_listen_fd);
goto failed;
}
return 0;
failed:
(void)close(s_listen_fd);
s_listen_fd = -1;
return -1;
}
/**
* 响应异常信号,令程序异常退出
*/
static void sig_abort(int signo)
{
static int abort_count = 0;
if (abort_count++ == 0){
void* array[32];
char buf[256];
int fd = open("/var/sangfor/testd.bt", O_RDWR|O_TRUNC|O_CREAT);
if (fd == -1){
fd = 2; //输出到标准错误输出
}
int len = sprintf(buf, "signal %s capture, backtrace:\n", signo);
write(fd, buf, len);
int size = backtrace(array, 32);
backtrace_symbols_fd(array, size, fd);
close(fd);
}
kill(getpid(), SIGKILL);
}
/**
* 程序正常退出
*/
static void sig_exit(int signo)
{
close_all_worker();
close_listener();
exit(0);
}
/**
* 调试信号响应函数
*/
static void sig_sangfor_debug(int signo)
{
debug_signo_activated = TRUE;
}
/**
* 释放所有接入连接
*/
static void sig_reset(int signo)
{
close_all_worker();
}
/**
* 初始化信号集,默认不开启COREDUMP
*/
static void init_signal(void)
{
signal(SIGTERM, sig_exit); //终端杀死
signal(SIGINT, sig_exit); //ctrl + c
signal(SIGQUIT, sig_exit); //处理程序退出
signal(SIGHUP, sig_exit); //终端关闭
signal(SIGSEGV, sig_abort); //段错误
signal(SIGILL, sig_abo


1楼2018-03-21 09:52回复