实现多线程并发服务器和多进程并发服务器(Linux网络编程)

多进程并发服务器

实现流程

	1. Socket();		创建 监听套接字 lfd
	2. Bind()	绑定地址结构 Strcut scokaddr_in addr;
	3. Listen();	
	4. while (1) {

		cfd = Accpet();			接收客户端连接请求。
		pid = fork();
		if (pid == 0){			子进程 read(cfd) --- 小写->大写 --write(cfd)			

			close(lfd)		关闭用于建立连接的套接字 lfd

			read()
			//小写转大写代码
			write()

		} else if (pid > 0{	

			close(cfd);		关闭用于与客户端通信的套接字 cfd	
			continue;
		}
	  }

	5. 子进程:

		close(lfd)

		read()

		小写->大写

		write()	

	   父进程:

		close(cfd);

		注册信号捕捉函数:	SIGCHLD

		在回调函数中, 完成子进程回收

			whilewaitpid();

read 函数的返回值:

	1. > 0 实际读到的字节数

	2. = 0 已经读到结尾(对端已经关闭)【 !重 !点 !】

	3. -1 应进一步判断errno的值:

		errno = EAGAIN or EWOULDBLOCK: 设置了非阻塞方式 读。 没有数据到达。 

		errno = EINTR 慢速系统调用被 中断。

		errno = “其他情况” 异常。

代码

#include <stdio.h>  
#include <ctype.h>  
#include <stdlib.h>  
#include <sys/wait.h>  
#include <string.h>  
#include <strings.h>  
#include <unistd.h>  
#include <errno.h>  
#include <signal.h>  
#include <sys/socket.h>  
#include <arpa/inet.h>  
#include <pthread.h>  
  
#include "wrap.h"  
  
#define SRV_PORT 9999  
  
void catch_child(int signum)  
{  
    while ((waitpid(0, NULL, WNOHANG)) > 0);  
    return ;  
}  
  
int main(int argc, char *argv[])  
{  
    int lfd, cfd;  
    pid_t pid;  
    struct sockaddr_in srv_addr, clt_addr;  
    socklen_t clt_addr_len;   
    char buf[BUFSIZ];  
    int ret, i;  
  
    //memset(&srv_addr, 0, sizeof(srv_addr));                 // 将地址结构清零  
    bzero(&srv_addr, sizeof(srv_addr));  
  
    srv_addr.sin_family = AF_INET;  
    srv_addr.sin_port = htons(SRV_PORT);  
    srv_addr.sin_addr.s_addr = htonl(INADDR_ANY);  
  
    lfd = Socket(AF_INET, SOCK_STREAM, 0);  
  
    Bind(lfd, (struct sockaddr *)&srv_addr, sizeof(srv_addr));  
  
    Listen(lfd, 128);  
  
    clt_addr_len = sizeof(clt_addr);  
  
    while (1) {  
  
        cfd = Accept(lfd, (struct sockaddr *)&clt_addr, &clt_addr_len);  
  
        pid = fork();  
        if (pid < 0) {  
            perr_exit("fork error");  
        } else if (pid == 0) {  
            close(lfd);  
            break;          
        } else {  
            struct sigaction act;  
  
            act.sa_handler = catch_child;  
            sigemptyset(&act.sa_mask);  
            act.sa_flags = 0;  
  
            ret = sigaction(SIGCHLD, &act, NULL);  
            if (ret != 0) {  
               perr_exit("sigaction error");  
            }  
            close(cfd);   
            continue;  
        }  
    }  
  
    if (pid == 0) {  
        for (;;) {  
            ret = Read(cfd, buf, sizeof(buf));  
            if (ret == 0) {  
                close(cfd);  
                exit(1);  
            }   
  
            for (i = 0; i < ret; i++)  
                buf[i] = toupper(buf[i]);  
  
            write(cfd, buf, ret);  
            write(STDOUT_FILENO, buf, ret);  
        }  
    }  
  
    return 0;  
}  

多线程并发服务器

实现流程

1. Socket();		创建 监听套接字 lfd

	2. Bind()		绑定地址结构 Strcut scokaddr_in addr;

	3. Listen();		

	4. while (1) {		

		cfd = Accept(lfd, );

		pthread_create(&tid, NULL, tfn, (void *)cfd);

		pthread_detach(tid);  				// pthead_join(tid, void **);  新线程---专用于回收子线程。
	  }

	5. 子线程:

		void *tfn(void *arg) 
		{
			// close(lfd)			不能关闭。 主线程要使用lfd

			read(cfd)--write(cfd)

			pthread_exit((void *)10;	
		}

代码

#include <stdio.h>  
#include <string.h>  
#include <arpa/inet.h>  
#include <pthread.h>  
#include <ctype.h>  
#include <unistd.h>  
#include <fcntl.h>  
  
#include "wrap.h"  
  
#define MAXLINE 8192  
#define SERV_PORT 8000  
  
struct s_info {                     //定义一个结构体, 将地址结构跟cfd捆绑  
    struct sockaddr_in cliaddr;  
    int connfd;  
};  
  
void *do_work(void *arg)  
{  
    int n,i;  
    struct s_info *ts = (struct s_info*)arg;  
    char buf[MAXLINE];  
    char str[INET_ADDRSTRLEN];      //#define INET_ADDRSTRLEN 16  可用"[+d"查看  
  
    while (1) {  
        n = Read(ts->connfd, buf, MAXLINE);                     //读客户端  
        if (n == 0) {  
            printf("the client %d closed...\n", ts->connfd);  
            break;                                              //跳出循环,关闭cfd  
        }  
        printf("received from %s at PORT %d\n",  
                inet_ntop(AF_INET, &(*ts).cliaddr.sin_addr, str, sizeof(str)),  
                ntohs((*ts).cliaddr.sin_port));                 //打印客户端信息(IP/PORT)  
  
        for (i = 0; i < n; i++)   
            buf[i] = toupper(buf[i]);                           //小写-->大写  
  
        Write(STDOUT_FILENO, buf, n);                           //写出至屏幕  
        Write(ts->connfd, buf, n);                              //回写给客户端  
    }  
    Close(ts->connfd);  
  
    return (void *)0;  
}  

2.int main(void)  
3.{  
4.    struct sockaddr_in servaddr, cliaddr;  
5.    socklen_t cliaddr_len;  
6.    int listenfd, connfd;  
7.    pthread_t tid;  
8.  
9.    struct s_info ts[256];      //创建结构体数组.  
10.    int i = 0;  
11.  
12.    listenfd = Socket(AF_INET, SOCK_STREAM, 0);                     //创建一个socket, 得到lfd  
13.  
14.    bzero(&servaddr, sizeof(servaddr));                             //地址结构清零  
15.    servaddr.sin_family = AF_INET;  
16.    servaddr.sin_addr.s_addr = htonl(INADDR_ANY);                               //指定本地任意IP  
17.    servaddr.sin_port = htons(SERV_PORT);                                       //指定端口号   
18.  
19.    Bind(listenfd, (struct sockaddr *)&servaddr, sizeof(servaddr));             //绑定  
20.  
21.    Listen(listenfd, 128);                                                      //设置同一时刻链接服务器上限数  
22.  
23.    printf("Accepting client connect ...\n");  
24.  
25.    while (1) {  
26.        cliaddr_len = sizeof(cliaddr);  
27.        connfd = Accept(listenfd, (struct sockaddr *)&cliaddr, &cliaddr_len);   //阻塞监听客户端链接请求  
28.        ts[i].cliaddr = cliaddr;  
29.        ts[i].connfd = connfd;  
30.  
31.        pthread_create(&tid, NULL, do_work, (void*)&ts[i]);  
32.        pthread_detach(tid);                                                    //子线程分离,防止僵线程产生.  
33.        i++;  
34.    }  
35.  
36.    return 0;  
37.}  
  • 3
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
### 回答1: 《Linux多线程服务器编程PDF》是一本关于在Linux系统下进行多线程服务器编程的电子书。它主要讲解了如何利用Linux多线程技术来搭建高性能的服务器应用程序。 这本书首先介绍了多线程编程的基本概念和原理,包括线程的创建与销毁、线程同步与互斥、线程调度等。然后,针对服务器应用开发过程中的常见问题,详细讲解了如何利用多线程解决这些问题,比如如何处理多个客户端的并发请求、如何实现高效的请求处理、如何解决资源竞争和线程安全等。 除了基础知识和问题解决方法,本书还深入探讨了多线程服务器的性能优化技巧。作者通过实例演示了如何利用线程池、异步IO和事件驱动等技术来提高服务器并发性能和响应速度。同时,还介绍了一些常用的性能监测工具和调优方法,帮助读者找出性能瓶颈并进行优化。 阅读这本书可以帮助读者掌握Linux多线程服务器编程的核心技术,从而设计和实现高性能、稳定性好的服务器应用程序。无论是对于专业开发人员还是对于对服务器编程感兴趣的学习者来说,都是一本非常实用的参考书籍。 ### 回答2: 《Linux多线程服务器编程PDF》是一本关于如何在Linux环境下进行多线程服务器编程的书籍。这本书主要介绍了如何利用Linux操作系统的特性来实现高效的多线程服务器程序。 在这本书中,首先会介绍多线程服务器编程的基础知识,包括线程和进程的概念,以及多线程编程的优势和挑战。然后,会详细讲解如何使用Linux提供的系统调用和库函数来创建和管理线程,以及如何利用线程之间的同步和互斥机制来实现高效的并发处理。 此外,书中还会介绍如何利用Linux提供的网络编程接口来实现基于TCP/IP协议的网络通信。它将介绍如何创建和管理套接字,以及如何使用套接字进行客户端和服务器之间的通信。同时,也会介绍如何使用多线程来处理多个客户端的请求,以及如何利用线程池来优化服务器的性能。 除了介绍基本的多线程服务器编程技术之外,这本书还会介绍一些高级的主题,如如何处理并发访问共享资源的问题,如何利用信号来实现进程间的通信,以及如何使用多进程多线程的混合编程模型。 总之,这本《Linux多线程服务器编程PDF》是一本全面而实用的指南,适合对多线程服务器编程感兴趣的读者学习和参考。通过学习这本书,读者可以了解到在Linux环境下如何编写高效且稳定的多线程服务器程序,提高应对高并发访问的能力,并为实际项目开发提供指导和支持。 ### 回答3: 《Linux多线程服务器编程》是一本介绍在Linux环境下开发多线程服务器程序的PDF电子书。本书主要内容包括多线程编程的基础知识、线程间同步与通信、线程池的设计与实现多线程服务器的模型与架构等。这本书通过详细讲解多线程编程的原理、技巧和注意事项,帮助读者理解多线程服务器的基本概念和工作原理,掌握多线程编程的核心技术。 《Linux多线程服务器编程》首先介绍了多线程编程的基本概念和背景,包括线程的定义、线程的创建与销毁、线程的同步与互斥等。然后,书中详细讲解了多线程编程中常用的同步与通信机制,如互斥量、条件变量、信号量等,以及它们的具体应用场景和用法。 接着,本书介绍了线程池的设计与实现。线程池是一种常用的服务器编程模型,可以提高服务器的性能和可扩展性。本书详细讲解了线程池的设计原理、线程池的管理与调度算法,以及线程池在实际服务器程序中的应用。通过学习线程池的设计与实现,读者可以更好地理解服务器程序的并发模型和性能优化技巧。 最后,本书介绍了多线程服务器的模型与架构。通过实际案例和代码示例,读者可以了解到多线程服务器的常用设计模式和架构思想,如单线程多路复用模型、多线程非阻塞模型等。这些模型和思想可以帮助读者设计和开发高性能、稳定可靠的多线程服务器程序。 综上所述,《Linux多线程服务器编程》是一本非常实用和全面的指南,适合对Linux服务器编程感兴趣的读者学习和参考。无论是初学者还是有一定经验的程序员,都可以通过阅读本书,全面提升自己在多线程服务器编程方面的能力和水平。

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值