百度云免费做网站,龙岩网站设计制作,网站一级导航怎么做,网络科技公司有什么职位1. 创建一个多进程服务器和多线程服务器
a. 多进程
#includemyhead.h
#define PORT 9999 //端口号
#define IP 192.168.125.113 //IP地址//定义信号处理函数#xff0c;用于回收僵尸进程
void handler(int signo)
{if(signo S…1. 创建一个多进程服务器和多线程服务器
a. 多进程
#includemyhead.h
#define PORT 9999 //端口号
#define IP 192.168.125.113 //IP地址//定义信号处理函数用于回收僵尸进程
void handler(int signo)
{if(signo SIGCHLD){while(waitpid(-1, NULL, WNOHANG) 0 );}
}//定义处理客户端操作的函数
int deal_cli_msg(int newfd, struct sockaddr_in cin)
{//5、收发数据char rbuf[128] ; //读取消息的容器while(1){//清空内容bzero(rbuf, sizeof(rbuf));int res recv(newfd, rbuf, sizeof(rbuf), 0);if(res 0){printf(客户端下线\n);break;}printf([%s:%d] : %s\n, inet_ntoa(cin.sin_addr), ntohs(cin.sin_port), rbuf);//链接一个字符串后发回去strcat(rbuf, *_*);send(newfd, rbuf, sizeof(rbuf), 0);//功能向newfd文件描述符中以阻塞形式写入数据}close(newfd);return 0;
}/**********************************主程序***************************************/
int main(int argc, const char *argv[])
{//将SIGCHLD信号与信号处理函数进行绑定if(signal(SIGCHLD, handler) SIG_ERR){perror(signal error);return -1;}//1、创建套接字int sfd -1;//功能创建一个支持TCP通信的套接字//AF_INET:表示跨主机的IPv4的通信//SOCK_STREAM:表示支持TCP通信if((sfd socket(AF_INET, SOCK_STREAM, 0)) -1){perror(socket error);return -1;}printf(sfd %d\n, sfd); ////设置端口号快速重用int reuse 1;if(setsockopt(sfd, SOL_SOCKET, SO_REUSEADDR, reuse, sizeof(reuse))-1){perror(setsockopt error);return -1;}//2、绑定地址信息结构体必须//2.1 填充地址信息结构体struct sockaddr_in sin;sin.sin_family AF_INET; //地址族为IPv4sin.sin_port htons(PORT); //端口号需要转换网络字节序sin.sin_addr.s_addr inet_addr(IP); //IP地址//2.2绑定工作if(bind(sfd, (struct sockaddr*)sin, sizeof(sin)) -1){perror(bind error);return -1;}printf(bind success _%d_%s_%s\n, __LINE__, __FILE__, __func__);//3、将套接字设置成被动监听状态if(listen(sfd, 128) -1){perror(listen error);return -1;}printf(listen success _%d_%s_%s\n, __LINE__, __FILE__, __func__);//4、接收链接请求//4.1 定义用于接收客户端地址信息的结构体变量struct sockaddr_in cin;socklen_t socklen sizeof(cin); //接收长度//4.2 接收客户端链接请求int newfd -1; //用于跟客户端通信的套接字文件描述符pid_t pid -1; //接收子进程pid号while(1){//fork()接收客户端链接请求//当执行到accept时系统会给该函数预分配一个文件描述符按最小未使用原则//所以在该函数阻塞时即使有旧的客户端退释放了文件描述符也不会再使用新释放的文件描述符//下一次阻塞时会预选上一次释放的文件描述符if( (newfdaccept(sfd, (struct sockaddr*)cin, socklen)) -1){perror(accept error);return -1;}printf([%s:%d] 连接成功, newfd %d\n, inet_ntoa(cin.sin_addr),\ntohs(cin.sin_port), newfd); //?//创建子进程用于跟新的客户端进行通信工作pid fork();if(pid 0){//父进程用于接收客户端连接请求//父进程中关闭newfdclose(newfd);}else if(pid 0){//关闭sfdclose(sfd);//调用处理客户端信息的函数deal_cli_msg(newfd, cin);//退出子进程exit(EXIT_SUCCESS);}else {perror(fork error);return -1;}//wait(NULL); //不能使用阻塞方式回收}//关闭套接字close(sfd);return 0;
}
b. 多线程
#includemyhead.h
#define PORT 9999 //端口号
#define IP 192.168.125.113 //IP地址//定义向线程体中传递参数的结构体类型
struct pthread_ds
{int newfd; //处理客户端的套接字文件描述符struct sockaddr_in cin; //客户端套接字地址信息结构体变量
};//定义线程处理函数
void *deal_cli_msg(void *arg)
{//分解传过来的参数int newfd ((struct pthread_ds*)arg)-newfd; struct sockaddr_in cin ((struct pthread_ds*)arg)-cin;//5、收发数据char rbuf[128] ; //读取消息的容器while(1){//清空内容bzero(rbuf, sizeof(rbuf));int res recv(newfd, rbuf, sizeof(rbuf), 0);if(res 0){printf(客户端下线\n);break;}printf([%s:%d] : %s\n, inet_ntoa(cin.sin_addr), ntohs(cin.sin_port), rbuf);//链接一个字符串后发回去strcat(rbuf, *_*);send(newfd, rbuf, sizeof(rbuf), 0);//功能向newfd文件描述符中以阻塞形式写入数据}close(newfd);//退出线程pthread_exit(NULL);}/****************************主程序***********************/
int main(int argc, const char *argv[])
{//1、创建套接字int sfd -1;//功能创建一个支持TCP通信的套接字//AF_INET:表示跨主机的IPv4的通信//SOCK_STREAM:表示支持TCP通信if((sfd socket(AF_INET, SOCK_STREAM, 0)) -1){perror(socket error);return -1;}printf(sfd %d\n, sfd); ////设置端口号快速重用int reuse 1;if(setsockopt(sfd, SOL_SOCKET, SO_REUSEADDR, reuse, sizeof(reuse))-1){perror(setsockopt error);return -1;}//2、绑定地址信息结构体必须//2.1 填充地址信息结构体struct sockaddr_in sin;sin.sin_family AF_INET; //地址族为IPv4sin.sin_port htons(PORT); //端口号需要转换网络字节序sin.sin_addr.s_addr inet_addr(IP); //IP地址//2.2绑定工作if(bind(sfd, (struct sockaddr*)sin, sizeof(sin)) -1){perror(bind error);return -1;}printf(bind success _%d_%s_%s\n, __LINE__, __FILE__, __func__);//3、将套接字设置成被动监听状态if(listen(sfd, 128) -1){perror(listen error);return -1;}printf(listen success _%d_%s_%s\n, __LINE__, __FILE__, __func__);//4、接收链接请求//4.1 定义用于接收客户端地址信息的结构体变量struct sockaddr_in cin;socklen_t socklen sizeof(cin); //接收长度//4.2 接收客户端链接请求int newfd -1; //用于跟客户端通信的套接字文件描述符pthread_t tid -1; //接收线程号while(1){//接收客户端链接请求if( (newfdaccept(sfd, (struct sockaddr*)cin, socklen)) -1){perror(accept error);return -1;}printf([%s:%d] 连接成功, newfd %d\n, inet_ntoa(cin.sin_addr),\ntohs(cin.sin_port), newfd); //?//定义一个向线程体传递的结构体变量struct pthread_ds info {newfd, cin};//创建一个分支线程用于跟客户端进行通信if(pthread_create(tid, NULL, deal_cli_msg, info) ! 0){printf(tid create error\n);return -1;}//回收线程资源//pthread_join(tid); //不能使用阻塞形式回收线程资源pthread_detach(tid); //将线程设置成分离态}//关闭套接字close(sfd);return 0;
}