前言:整个程序的架构就是一开始创建一个线程,在这个线程里面做下面几个操作:
1、调用socket,创建监听客户端的socket
2、设置socket属性,端口可以重用
3、调用bind,绑定地址和端口
4、调用listen,开始监听
5、调用while(1)循环
6、 每新连接一个就创建一个线程用来做连接处理
while(1)
{
//调用accept,返回与服务器连接的客户端描述符
if ((connectfd = accept(listenfd,(struct sockaddr *)&client,(socklen_t *)&sin_size))==-1) {
sys_err("accept() error\n");
}
//多线程初始化
void server_init()
{
pthread_t thdrec;
pthread_attr_t attr;
if(pthread_attr_init(&attr))
{
printf("pthread init error\n");
}
//threadfunc defined in netmsg.h
if(pthread_create(&thdrec,&attr,threadfunc,0))
{
printf("creat pthread error\n");
}
}
//在多线程中开启监听
void *threadfunc(void * arg)
{
printf("threadfunc\n");
uint16_t port = 9000;
tcp_server(port);
}
//绑定端口后开始监听端口
void tcp_server(uint16_t port)//this port unused
{
int listenfd; //socket描述符
struct sockaddr_in server; //服务器地址信息结构体
//调用socket,创建监听客户端的socket
if ((listenfd = socket(AF_INET, SOCK_STREAM, 0)) == -1) {
sys_err("Creating socket failed.");
}
//设置socket属性,端口可以重用
int opt = SO_REUSEADDR;
setsockopt(listenfd, SOL_SOCKET, SO_REUSEADDR, &opt, sizeof(opt));
//初始化服务器地址结构体
bzero(&server,sizeof(server));
server.sin_family=AF_INET;
server.sin_port=htons(PORT);
server.sin_addr.s_addr = htonl (INADDR_ANY);
//调用bind,绑定地址和端口
if (bind(listenfd, (struct sockaddr *)&server, sizeof(struct sockaddr)) == -1) {
sys_err("Bind error.");
}
//调用listen,开始监听
if(listen(listenfd,BACKLOG) == -1){
sys_err("listen() error\n");
}
//处理客户端链接的接收工作
accept_conn(listenfd);
//关闭监听socket
close(listenfd);
}
//处理客户端链接的接收工作*
void accept_conn(int listenfd)
{
int connectfd; //socket描述符
pthread_t connectthread; //线程体变量
ARG *arg; //客户端结构体变量
struct sockaddr_in client; //客户端地址信息结构体
int sin_size = sizeof(struct sockaddr_in);
pthread_attr_t attr;
while(1) {
//调用accept,返回与服务器连接的客户端描述符
if ((connectfd = accept(listenfd,(struct sockaddr *)&client,(socklen_t *)&sin_size))==-1) {
sys_err("accept() error\n");
}
arg = new ARG;
arg->connfd = connectfd;
sendfd = connectfd;
memcpy(&arg->client, &client, sizeof(client));
//创建线程,以客户端连接为参数,start_routine为线程执行函数
pthread_attr_init (&attr);
pthread_attr_setdetachstate (&attr, PTHREAD_CREATE_DETACHED);
if (pthread_create(&connectthread, &attr, start_routine, (void*)arg)) {
sys_err("Pthread_create() error");
}
pthread_attr_destroy (&attr);
}
}
void process_cli(int connectfd, struct sockaddr_in client); //客户端请求处理函数
void* start_routine(void* arg); //线程处理函数
typedef struct _ARG {
int connfd;
struct sockaddr_in client;
}ARG; //客户端结构体
void* start_routine(void* arg)
{
ARG *info = (ARG *)arg;
process_cli(info->connfd, info->client);
//删除对应的堆内存
delete info;
pthread_exit(NULL);
}
void process_cli(int connectfd, sockaddr_in client)
{
hiBsp_Size size;
hiBsp_Rect rect;
int x,y;
int num;
char recvbuf[MAXDATASIZE], sendbuf[MAXDATASIZE], cli_name[MAXDATASIZE];
wSip_Msg2 dev_msg;
printf("You got a connection from %s. \n",inet_ntoa(client.sin_addr) );
//MSG_WAITALL
while ((num = recv(connectfd, recvbuf, MAXDATASIZE,0)) > 0)
{
recvbuf[num] = '\0';
printf("Received size( %d ) message: %x\n",num, recvbuf);
for(int i=0;i<num-1;i++)
{
//printf(" %x",recvbuf[i]);
}
}
close(connectfd);
}