第一节中讲述的简单的客户端服务器代码,那样的代码处理请求量比较少且不需要长占用的服务比较合适,当请求比较多的时候,利用上述的结构就不能满足需要,类似于ftp服务,每个服务都会占有一个套接字很长时间,而且同时可能有多个客户连接,面对这种多客户,高流量的情况,需要一种不同于简单客户端服务器那样的模式解决,这篇文章就先介绍OCOT。
OCOT是one client one thread的简写,从字面上就可以理解,每当有一个客户连接过来,都会有一个线程为其服务,不管这个线程是预先创建的还是临时创建的。当每个客户都有专门的线程为其服务时,就可以解决上述问题。
利用OCOT为多客户服务时,适应于连接数量有限,而且连接希望是长连接的情况,如果海量的短连接时则不适宜利用OCOT,究其原因无非是频繁的CPU执行权的切换会导致效率底下。
至于如果解决海量短连接的情况,以后再说。下面还是给一个简单的例子,其实应该给一个简单的ftp雏形的,不过为了简单,还是给一个简单点吧!
服务端源代码:
1 #include <iostream>
2 #include <sys/socket.h>
3 #include <sys/types.h>
4 #include <arpa/inet.h>
5 #include <pthread.h>
6 using namespace std;
7
8 void* thread_func(void* arg);
9
10 int main()
11 {
12 //create socket
13 int listen_sock = socket(AF_INET,SOCK_STREAM,0);
14 if(listen_sock < 0)
15 {
16 cout << "create socket error" << endl;
17 return -1;
18 }
19
20 struct sockaddr_in address;
21 address.sin_family = AF_INET;
22 address.sin_port = htons(5656);
23 address.sin_addr.s_addr = htonl(INADDR_ANY);
24
25 if(bind(listen_sock,(struct sockaddr*)&address,sizeof(address)) < 0)
26 {
27 cout << "bind socket error" << endl;
28 close(listen_sock);
29 return -1;
30 }
31
32 listen(listen_sock,10);
33
34 while(true)
35 {
36 void *ret;
37 int sock = accept(listen_sock,NULL,NULL);
38 pthread_t tid;
39 pthread_create(&tid,NULL,thread_func,&sock);
40 // pthread_join(tid,&ret);
41 sleep(1);
42
43 }
44
45 close(listen_sock);
46 return 0;
47 }
48
49 // thread function
50 void* thread_func(void *arg)
51 {
52 int sock = *((int*)arg);
53 cout << pthread_self() <<" send data" << endl;
54 send(sock,"hello world",strlen("hello world")+1,0);
55 close(sock);
56
57 return (void*)0;
58 }
59