c语言实现-socket之select

本文介绍如何使用Linux Socket和Select函数结合实现一个简单的HTTP服务器,通过Socket监听客户端连接并使用Select进行高效的数据读取和处理。

摘要生成于 C知道 ,由 DeepSeek-R1 满血版支持, 前往体验 >

#include <stdio.h>
#include <sys/types.h>
#include <sys/socket.h>
#include <sys/select.h>
#include <errno.h>
#include <netinet/in.h>
#include <unistd.h>
#include <arpa/inet.h>
#include <stdlib.h>

#define LISTENQ 5
#define OPEN_MAX 1024
#define SERV_PORT 60088
#define MAX_LINE 1024
#define INFTIM -1

#define MAXEVENTS 1000

char szHtmlBuf[] = "HTTP/1.1 200 OK\r\n"
"Date: Mon, 02 Feb 2015 03:44:06 GMT \r\n"
"Expires:0 \r\n"
"Vary: Accept-Encoding\r\n"
"Content-Type: text/html; charset=gb2312\r\n"
"Content-Length: 46\r\n"
"\r\n"
"<html> <head>Welcome !!!</head> <body>LINUX SELECT</body></html>";

fd_set fds;

void echo_srv(int clientFd)
{
char line[MAX_LINE];
printf(" starting read data ... \n");
int n = read(clientFd, line, sizeof(line));
if(n < 0) {
if(errno == ECONNRESET)
{
close(clientFd);
FD_CLR(clientFd, &fds);
printf(" network error! \n ");
}
else
{
printf(" network exception! \n ");
exit(-1);
}
}
else if(n == 0)
{
close(clientFd);
FD_CLR(clientFd, &fds);
printf( " normal return! \n " );
}
else
{
line[n] = 0;
printf("receive data %s \n ", line);

write(clientFd, szHtmlBuf, sizeof(szHtmlBuf));
}
}

int main()
{
struct sockaddr_in cliaddr, servaddr;
int listenFd = socket(AF_INET, SOCK_STREAM, 0);
if( listenFd < 0)
{
printf(" socket function exec fail! \n ");
return 1;
}

servaddr.sin_family = AF_INET;
servaddr.sin_addr.s_addr = htonl(INADDR_ANY);

servaddr.sin_port = htons(SERV_PORT);
if(bind(listenFd, (struct sockaddr*)&servaddr, sizeof(servaddr)) < 0)
{
printf("bind function exec fail! \n ");
return 1;
}

if(listen(listenFd, LISTENQ) < 0)
{
printf("listen function exec fail! \n");
return 1;
}
printf("listen function exec success! \n");

int maxfd;
FD_ZERO(&fds);

do{
FD_SET(listenFd, &fds);
maxfd = listenFd + 1;
int nRead = 0;
if( (nRead = select(maxfd + 1, &fds, NULL, NULL, NULL)) < 0)
{
printf("select fail! \n");
exit(-1);
}
printf("select find data Change\n");

int i;
for( i = 0; i <= maxfd && nRead > 0; i++)
{
if(!FD_ISSET(i, &fds))
{
continue;
}
--nRead;
if(i == listenFd)
{
socklen_t clilen = sizeof(cliaddr);
int connfd = accept(listenFd, (struct sockaddr*)&cliaddr, &clilen);
if(connfd < 0)
{
if ((errno != EAGAIN) && (errno != EWOULDBLOCK))
{
printf( "fail to accept new client \n");
continue;
}
}
printf("Ip: %s come here !\n", inet_ntoa(cliaddr.sin_addr));
FD_SET(connfd, &fds);
maxfd = (connfd > maxfd ? connfd : maxfd);
}
else
{
echo_srv(i);
}
}

}while(1);

return 0;
}

编译:gcc -o select_socket select_socket_linux.c
启动:./select_socket
服务器打印:
listen function exec success!

在浏览器中访问:http://{IP}:60088
返回:

<html> <head>Welcome !!!</head> <body>LINUX SE

服务器打印:
select find data Change
Ip: {C-IP} come here !
select find data Change
starting read data ...
receive data GET / HTTP/1.1
Host: {IP}:60088
Connection: keep-alive
Accept: text/html,application/xhtml+xml,application/xml;q=0.9,image/webp,*/*;q=0.8
User-Agent: Mozilla/5.0 (Windows NT 6.1; WOW64) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/39.0.2171.95 Safari/537.36
Accept-Encoding: gzip, deflate, sdch
Accept-Language: zh-CN,zh;q=0.8
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值