第一节中讲述的简单的客户端服务器代码,那样的代码处理请求量比较少且不需要长占用的服务比较合适,当请求比较多的时候,利用上述的结构就不能满足需要,类似于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