1.多线程服务器的实现是在多进程服务器的基础上增改了一些功能
创建流程:
1.套接字的创建,ip地址初始化
2.bind使套接字与主机捆绑
3.listen()建立监听;
4.通信模块:read函数将读取的数据保存在数组中
5.主函数:调用函数完成套接字的创建等基本步骤
accept函数
创建线程,对通信模块的调用
#define IP "0"
#define PORT 7777
#define BACKLOG 1000
//初始化服务器
int init_sever(char *ip,int port,int backlog)
{
int listenfd = socket(PF_INET,SOCK_STREAM,0);
if(-1 == listenfd)
{
perror("listen");
exit(-1);
}
struct sockaddr_in seraddr = {0};
seraddr.sin_family = PF_INET;
seraddr.sin_port = htons(port);
seraddr.sin_addr.s_addr = inet_addr(ip);
//地址复用
int opt = 1;
setsockopt(listenfd,SOL_SOCKET,SO_REUSEADDR,&opt,sizeof(opt));
//连接主机
int ret = bind(listenfd,(struct sockaddr *)&seraddr,sizeof(seraddr));
if(-1 == ret)
{
perror("bind");
exit(-1);
}
//设置监听
ret = listen(listenfd,backlog);
if(-1 == ret)
{
perror("listen");
exit(-1);
}
return listenfd;
}
//通信功能函数
void *client_con(void *pthread)
{
int connfd = *(int *)pthread;
char buf[BUFSIZ] = {0};
int cli_say;
while(1)
{
memset(buf,0,sizeof(buf));
cli_say = read(connfd,buf,BUFSIZ);
if(-1 == cli_say)
{
perror("read");
close(connfd);
exit(-1);
}
else if(0 == cli_say)
{
perror("read");
exit(0);
}
printf("client say:%s\n",buf);
if(strncmp(buf,"sl",2) == 0)
{
printf("train running...\n");
system("sl");
}
}
}
主函数代码:
//主函数
int main(int argc, char *argv[])
{
int connfd; //通信套接字
int listenfd; //监听套接字
listenfd = init_sever(IP,PORT,BACKLOG); //调用套接字的创建等功能函数
if(-1 == listenfd)
{
perror("init failed..");
exit(-1);
}
printf("init success\n");
while(1)
{
struct sockaddr_in addr;
socklen_t len = sizeof(addr);
connfd = accept(listenfd,(struct sockaddr *)&addr,&len);
if(-1 == connfd)
{
perror("accept");
exit(-1);
}
printf("pthread num:%d---client ip:%s---client port:%d\n",connfd-3,inet_ntoa(addr.sin_addr),ntohs(addr.sin_port));
pthread_t tid; //创建线程
pthread_create(&tid,NULL,client_con,(void *)&connfd); //创建线程并调用通信模块,将通信套接字的信息给到该函数;
pthread_detach(tid); //非阻塞,子线程结束,回收资源
}
close(listenfd);
return 0;
}
线程相关函数:
pthread_t pid; //获取一个线程号
int pthread_create(pthread_t *thread, const pthread_attr_t *attr, void *(*start_routine) (void *), void *arg);
参数说明:thread:线程号
attr:线程的的属性,一般置为NULL,表示默认属性;
第三个是回掉函数,线程所要执行的功能;
第四个是回掉函数的参数;
pthread_detach();无阻塞回收结束的子进程的函数
pthread_join();阻塞回收结束的子进程的函数