您的位置:首页 > 理论基础 > 计算机网络

Unix网络编程——常见服务器模型

2017-03-05 23:56 741 查看
**

常见服务器模型:

**

- 循环服务器

- 并发服务器

简单的并发服务器模型

使用线程池或进程池的服务器模型

使用I/O复用的并发服务器模块

UDP循环服务器模型



// UDP循环服务器模型
struct sockaddr_in local_addr,accept_addr;
// 填充local_addr,略
// 使用SOCK_DGRAM调用socket创建UDP套接字
int sockfd = socket(AF_INET,SOCK_DGRAM,0);
bind(sockfd,(struct sockaddr *)&local_addr,sizeof(local_addr));
while(1){
recvfrom(sockfd,buf,sizeof(buf),0,(struct sockaddr*)&accept_addr,&len);
time_t now = time(NULL);
sprintf(buf,"%24s\n",ctime(&now));
sendto(sockfd,buf,strlen(buf),0,(struct sockaddr*)&accept_addr,len);
}


TCP循环服务器模型



// TCP循环服务器模型
int sockfd = socket(AF_INET,SOCK_STREAM,0);
struct sockaddr_in serv_addr,client_addr;
// 填充serv_addr
bind();
listen();
while(1){
int client_fd = accept(sockfd,(struct sockaddr*)&client_addr,&len);
// dosomething
close(client_fd);
}
close(sockfd);


简单的TCP并发服务器模型



// 简单的TCP并发服务器模型
int sockfd = socket(AF_INET,SOCK_STREAM,0);
struct sockaddr_in serv_addr,client_addr;
// 填充serv_addr
bind();
listen();
while(1){
int client_fd = accept(sockfd,(struct sockaddr*)&client_addr,&len);
if(fork() == 0){
// dosomething for request
}
close(client_fd);
}
close(sockfd);


带线程池的TCP并发服务器模型

#include <sys/socket.h>
#include <sys/types.h>
#include <netinet/in.h>
#include <arpa/inet.h>
#include <pthread.h>

pthread_mutex_t alock = PTHREAD_MUTEX_INITITIALIZER;

static void *handle_request(void *argv){
int sockfd = *((int*)argv);
while(1){
pthread_mutex_lock(alock);
client_sock = accept();
pthread_mutex_unlock(alock);
// do something
}
}

static void handle_connect(int sockfd){
pthread_t thread_id[MAX_THREAD_NO];
int i;
for(i = 0;i < MAX_THREAD_NO;++i){
pthread_create(&thread_id[i],NULL,handle_request,(void *)&sockfd);
}
// 等待线程结束
for(i = 0;i < MAX_THREAD_NO;++i)
pthread_join(thread_id[i],NULL);
}

// 简单的TCP并发服务器模型
int main(){
int sockfd = socket(AF_INET,SOCK_STREAM,0);
struct sockaddr_in serv_addr,client_addr;
// 填充serv_addr
bind();
listen();
handle_connect(sockfd);
close(sockfd);
return 0;
}


这里的线程池也可以换成进程,即在listen完成后创建N个进程,然后分别进行accept。而且使用进程不需要加锁,因为套接字描述符是共享的,linux内核会保证只有一个进程成功accept到客户端的请求。

I/O复用循环式TCP服务器模型

见Unix网络编程—— I/O复用之select
内容来自用户分享和网络整理,不保证内容的准确性,如有侵权内容,可联系管理员处理 点击这里给我发消息