多连接Web服务器C

多连接Web服务器C,c,sockets,winapi,webserver,winsock,C,Sockets,Winapi,Webserver,Winsock,我需要用C编写一个非常基本的Web服务器。下面是我的代码 问题是,我无法正确管理多个连接,因为当我在浏览器上打开新选项卡时,我总是收到消息“Connection#1”,而不是“Connection#2”、“Connection#3” 错误在哪里?谢谢 这是我的密码 或在此: \ifdef\u WIN32 #包括 #定义套接字\u t套接字 #否则 #包括 #包括 #包括 #包括 #包括 #定义WSACleanup() #定义无效的_套接字(~0) #定义套接字错误-1 #定义closesocke

我需要用C编写一个非常基本的Web服务器。下面是我的代码

问题是,我无法正确管理多个连接,因为当我在浏览器上打开新选项卡时,我总是收到消息“Connection#1”,而不是“Connection#2”、“Connection#3”

错误在哪里?谢谢

这是我的密码 或在此:

\ifdef\u WIN32
#包括
#定义套接字\u t套接字
#否则
#包括
#包括
#包括
#包括
#包括
#定义WSACleanup()
#定义无效的_套接字(~0)
#定义套接字错误-1
#定义closesocketclose
#定义ioctlsocket ioctl
#定义套接字\u t int
#恩迪夫
#包括
#包括
#包括
#包括
#包括
无效打印时间(字符*buf,大小\u t buf\u len){
时间与时间;
时间(&rawtime);
结构tm信息;
#ifdef_WIN32
gmtime(信息和绘图时间);
#否则
gmtime_r(&rawtime,&info);
#恩迪夫
const char*days[]={“Sun”、“Mon”、“Tue”、“Wed”、“Thu”、“Fri”、“Sat”};
const char*months[]={“一月”、“二月”、“三月”、“四月”、“五月”、“六月”、“七月”、“八月”、“九月”、“十月”、“十一月”、“十二月”};
snprintf(基本单位,基本单位,“%s,%i%s%i%02i:%02i:%02i GMT”,日[info.tm\u wday],日[info.tm\u mday],月[info.tm\u mon],1900+年,
info.tm_小时、info.tm_分钟、info.tm_秒);
}
类型定义结构存储列表{
插座;
结构sock_list*下一步;
}袜子清单;
无效插座列表插入(插座列表**列表,插座){
sock_list*i=*list;
sock_list*j=*list;
sock_list*n=malloc(sizeof(sock_list));
n->s=s;
n->next=0;
而(i){
j=i;
i=i->next;
}
如果(j){
j->next=n;
}
否则{
*列表=n;
}
}
int sock_list_len(sock_list*list){
int c=0;
sock_list*i=列表;
而(i){
++c;
i=i->next;
}
返回c;
}
int main(){
int端口=80;
#ifdef_WIN32
WSADATA wsa;
if(WSAStartup(MAKEWORD(2,2),&wsa)!=0){
返回-1;
}
#恩迪夫
插座;
sock=socket(AF\u INET,sock\u STREAM,0);
if(sock==无效的_套接字){
printf(“无法打开套接字(-2)\n”);
WSACleanup();
返回-2;
}
无符号长模式=1;
ioctlsocket(sock、FIONBIO和&mode);//设置为非阻塞
服务器中的结构sockaddr_;
memset(&server,0,sizeof(server));
server.sinu family=AF\u INET;
server.sin\u addr.s\u addr=INADDR\u ANY;
server.sin_port=htons(端口);
if(绑定(sock,(struct sockaddr*)&server,sizeof(server))==SOCKET\u错误){
printf(“无法绑定套接字(-3)\n”);
插座;
WSACleanup();
返回-3;
}
听(sock,SOMAXCONN);
插座列表*连接列表=0;
对于(;;){
插座列表*i=连接列表;
fd_集;
FD_零位(&set);
而(i){
FD_集合(i->s和集合);
i=i->next;
}
选择(0,&集,&集,&集,0);
客户端中的结构sockaddr_;
memset(&client,0,sizeof(client));
int c=sizeof(客户);
socket\u t ns=accept(sock,(struct sockaddr*)和client,&c);
if(ns!=无效的\u插座){
printf(“新套接字%u\n”,ns);
插座列表插入(&conn列表,ns);
}
整数计数=0;
i=连接列表;
而(i){
++计数;
int recv_sz;
char-msg[4096];
char-tbuf[512];
打印时间(待定,512);
recv_sz=recv(i->s,msg,4096,0);
如果(recv_sz>0){
字符html[4096];
snprintf(html,4096,“再见”
“正文{边距:200px自动;文本对齐:居中;颜色:#3939;}”
“连接%i%s”,计数,待定);
snprintf(msg,4096,“HTTP/1.1 200确定\r\n内容长度:%i\r\n内容类型:text/html;charset=utf-8\r\n\r\n%s”,
strlen(html),
html);
发送(i->s,msg,strlen(msg),0);
printf(“发送到%u\n”,i->s);
}
i=i->next;
}
fflush(stdout);
#ifdef_WIN32
睡眠(1);
#否则
usleep(1000);
#恩迪夫
}
插座;
WSACleanup();
返回0;
}

由于以下代码,“计数”始终为1:

    int count = 0;
    i = conn_list;

    while (i)
    {
        ++count;
建议将“计数”的初始化移动到之前:

for (;;)
那么为什么每次都要为每个新连接重写所有HTML页面呢


我认为在发现新连接时只需编写一次特定的HTML页面

“我需要用C编写一个非常基本的Web服务器。”这显然不是C的目的,您应该改用python或类似的语言。C代表“complete http server”而不是“非常基本”,因为仅仅是“基本服务器”就需要大量的代码,而您的服务器将非常糟糕。不要重新发明轮子,而是使用一些库,例如:您的代码可能会卡在recv()中,因为您接受的套接字正在阻塞。此外,您还没有将侦听套接字(已使其成为非阻塞套接字)放入任何select()fdsetabout:
select(0,&set,&set,&set,&set,0)第一个参数不能为0,它必须是最大套接字值+1。第三个和第四个参数应为NULL,因为代码未检查写可用性或I/O异常。关于:
socket\u t ns=accept(sock,(struct sockaddr*)和client,&c)第三个参数的类型应为
socklen\u t
,而不是
int
for (;;)