gpt4 book ai didi

基于fork()的c服务器练习

转载 作者:行者123 更新时间:2023-11-30 20:37:52 25 4
gpt4 key购买 nike

我对我发现可以训练我的套接字能力的练习有一点疑问。练习中说:基于fork()编写tcp服务器的伪代码限制条件: - 最多 20000 个同时事件连接;在此限制之后,新连接将被丢弃 - 每个客户端(ip)每小时最多 1000 个请求

我已经草拟了一个解决方案,我想知道这是否是一个好方法:

struct client{
int ip;
timestamp to;
int n_req;
client* next;
}

void serve(int c_fd, int ip, client* list){
client* c = find_in_list(list, ip);

timestamp now = gettimeofday();
if(now.tv_sec - c->to.tv_sec > (60*60)){
// ig one hour is passed is possible to reset counter
c->n_req = 0;
c->to = now;
}
if(c->n_req > 1000){
/*do_nothing */
} else {
n_req++;
/*
do stuff
*/
}
exit();
}

int main(){
client* list = NULL;

a_fd = socket(AF_INET);
bind(a_fd);
listen(a_fd);


while(1){

/*inizilize poll*/
n_ready = poll();

if(n_ready > 0){

for(/*each ready file descriptor*/){
c_fd = accept(a_fd, this_sockaddr);

if(/* if the ip in this_sockaddr is new*/){
client* new = /*create neew client */;
add_list(list, new);
}

if(served <= 20000){
served++;

pid = fork();
if(pid == 0 ){ //CHILD
serve(c_fd, ip, list);
close(c_fd)
} else { //FATHER
close(c_fd);
do{
pid = blocking_wait();
served--;
} while(pid != 0)
}
} else {
close(c_fd);
}
}

}
}
}

感谢您的建议。

最佳答案

如果您想查看使用 fork 的服务器的简单但完全有效的示例,我建议您查看这个简单的小项目:

ftp://ftp.cs.umass.edu/pub/net/pub/kurose/ftpserver.c

   if (listen(sockid,5) < 0)
{ printf("server: listen error :%d\n",errno);exit(0);}

while(1==1) {
/* ACCEPT A CONNECTION AND THEN CREATE A CHILD TO DO THE WORK */
/* LOOP BACK AND WAIT FOR ANOTHER CONNECTION */
printf("server: starting accept\n");
if ((newsd = accept(sockid ,(struct sockaddr *) &client_addr,
&clilen)) < 0)
{printf("server: accept error :%d\n", errno); exit(0); }
printf("server: return from accept, socket for this ftp: %d\n",
newsd);
if ( (pid=fork()) == 0) {
/* CHILD PROC STARTS HERE. IT WILL DO ACTUAL FILE TRANSFER */
close(sockid); /* child shouldn't do an accept */
doftp(newsd);
close (newsd);
exit(0); /* child all done with work */
}
/* PARENT CONTINUES BELOW HERE */
close(newsd); /* parent all done with client, only child */
} /* will communicate with that client from now on */

子叉看起来像这样:

/* CHILD PROCEDURE, WHICH ACTUALLY DOES THE FILE TRANSFER */
doftp(int newsd)
{
int i,fsize,fd,msg_ok,fail,fail1,req,c,ack;
int no_read ,num_blks , num_blks1,num_last_blk,num_last_blk1,tmp;
char fname[MAXLINE];
char out_buf[MAXSIZE];
FILE *fp;

no_read = 0;
num_blks = 0;
num_last_blk = 0;


/* START SERVICING THE CLIENT */

/* get command code from client.*/
/* only one supported command: 100 - get a file */
req = 0;
if((readn(newsd,(char *)&req,sizeof(req))) < 0)
{printf("server: read error %d\n",errno);exit(0);}
req = ntohs(req);
...

关于基于fork()的c服务器练习,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/31574092/

25 4 0
Copyright 2021 - 2024 cfsdn All Rights Reserved 蜀ICP备2022000587号
广告合作:1813099741@qq.com 6ren.com