文章链接:https://codemouse.online/archives/2020-02-29-102714
设置服务器监听,获取fd
int SRV_create_listen_fd()
{
int listenfd = socket(AF_INET, SOCK_STREAM, 0);
if(listenfd == -1)
{
ERR_PRINT("socket fail, listenfd:%d\n",listenfd);
return false;
}
int on = 1;
if (setsockopt(listenfd, SOL_SOCKET, SO_REUSEADDR, &on, sizeof(on)) < 0)
{
ERR_PRINT("setsockopt fail\n");
return false;
}
struct sockaddr_in servaddr;
servaddr.sin_family = AF_INET;
servaddr.sin_port = htons(PORT);
servaddr.sin_addr.s_addr = htonl(INADDR_ANY);
//inet_pton(AF_INET, IP, &servaddr.sin_addr);
if(bind(listenfd, (struct sockaddr*)&servaddr, sizeof servaddr) < 0)
{
ERR_PRINT("bind fail\n");
return false;
}
//listen端口
if(listen(listenfd, LISTSIZE) < 0)
ERR_PRINT("listen fail\n");
return listenfd;
}
跨平台
#ifdef _WIN32
/*****************************************************************************
函 数 名 : Service.init_win_listen
功能描述 : 初始化监听的fd
-1:创建套接字错误.
-2:绑定错误
-3:监听错误
win特有:
-4:WSA初始化错误
输入参数 : const char *ip
int port
输出参数 : 无
返 回 值 : sockfd Service::
调用函数 :
被调函数 :
修改历史 :
1.日 期 : 2020年5月25日
作 者 : codeMouse
修改内容 : 新生成函数
*****************************************************************************/
int Service::initListen(const char *ip, int port)
{
//初始化WSA
WORD sockVersion = MAKEWORD(2, 2);
WSADATA wsaData;
if (WSAStartup(sockVersion, &wsaData) != 0)
{
printf("init WSA fail!\n");
return -4;
}
//创建套接字
SOCKET slisten = socket(AF_INET, SOCK_STREAM, IPPROTO_TCP);
if (slisten == INVALID_SOCKET)
{
printf("socket error !\n");
return -1;
}
//绑定IP和端口
struct sockaddr_in sin;
sin.sin_family = AF_INET;
sin.sin_port = htons(port);
sin.sin_addr.s_addr = inet_addr(ip);
//sin.sin_addr.s_addr = INADDR_ANY;
if (bind(slisten, (LPSOCKADDR)&sin, sizeof(sin)) == SOCKET_ERROR)
{
printf("bind error !\n");
closesocket(slisten);
return -2;
}
//开始监听
if (listen(slisten, 10) == SOCKET_ERROR)
{
printf("listen error !\n");
closesocket(slisten);
return -3;
}
printf("listen addr:%s port:%d\n", ip,port);
listenfd = slisten;
return 1;
}
#else
int Service::initListen(const char *ip, int port)
{
//1.creat socket
int slisten = socket(AF_INET,SOCK_STREAM,IPPROTO_TCP);
if(fd < 0){
perror("creat socket error\n");
return -1;
}
struct sockaddr_in sin;
sin.sin_family = AF_INET;
sin.sin_port = htons(port);
sin.sin_addr.s_addr = inet_addr(ip);//INADDR_ANY
//2.bind
if(bind(slisten,(struct sockaddr*)&sin,sizeof(sin)) < 0){
perror("bind error\n");
close(slisten);
return -2;
}
//3.listen
if(listen(slisten,10) < 0){
perror("listen error\n");
close(slisten);
return -3;
}
listenfd = slisten;
return 1;
}
#endif
获取客户端fd
void * SRV_accept_process(void *args)
{
int listenfd = atoi((char *)args);
int clifd = 0;
// 客户端参数
struct sockaddr_in tCliaddr;
socklen_t tCliaddlen;
tCliaddlen = sizeof(tCliaddr);
//int clifd = accept(listenfd, NULL, NULL);
ACCEPT:
clifd = accept(listenfd,(struct sockaddr*)(&tCliaddr), &tCliaddlen);
if(clifd == -1)
{
if(errno==EINTR)
{
goto ACCEPT;
}
else
{
ERR_PRINT("accept fail\n");
return NULL;
}
}
DBG_PRINT("accept new client(%d):%s:%d\n", clifd, inet_ntoa(tCliaddr.sin_addr),tCliaddr.sin_port);
return NULL;
}