网络编程;TCP多进程并发服务器;TCP多线程并发服务器;TCP网络聊天室和UDP网络聊天室;后面两个还没写出来;0911

思维导图

TCP多进程并发服务器

网络编程实现,一个服务器,一个客户端的通信;多进程并发;父进程非阻塞回收子进程资源

代码

复制代码
#include<myhead.h>
#define SER_IP "172.20.10.3" //服务器ip地址 虚拟机的
#define SER_PORT 8888

void handler(int signum)
{
	//判断 捕获到的信号是SIGCHLD
	if(signum == SIGCHLD)
	{
		//以非阻塞的方式回收僵尸进程
		while(waitpid(-1,NULL,WNOHANG)>0);
	}
}

/****************main function***************/
int main()
{
	//绑定SIGCHLD信号到处理函数中
	if(signal(SIGCHLD,handler)==SIG_ERR)
	{
		perror("signal error");
		return -1;
	}
	//1.创建一个用于连接的 套接字描述符
	int sfd = socket(AF_INET,SOCK_STREAM,0);
	if (sfd == -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("setsockopr error");
		return -1;
	}
	printf("端口已快速重用\n");

	//2.给套接字绑定ip地址和端口号
	//2.1 准备地址信息结构体
	struct sockaddr_in sin;
	sin.sin_family = AF_INET;//通信域地址族
	sin.sin_port = htons(SER_PORT);//服务器端口号
	sin.sin_addr.s_addr = inet_addr(SER_IP);
	//2.2 执行绑定工作
	if(bind(sfd,(struct sockaddr*)&sin,sizeof(sin))==-1)
	{
		perror("bind error");
		return -1;
	}
	printf("bind success");

	//3.将套接字 设置 被动监听状态
	if(listen(sfd,128)==-1)
	{
		perror("listen error");
		return -1;
	}
	printf("listen success\n");

	//4.阻塞等候 客户端的连接
	//4.1定义地址信息结构体,用于接收客户端地址信息
	struct sockaddr_in cin;
	socklen_t addrlen=sizeof(cin); //接收地址长度
	while(1)
	{
		//阻塞等待客户端连接
		int newfd = accept(sfd,(struct sockaddr*)&cin,&addrlen);
		if(newfd ==-1)
		{
			perror("accept error");
			return -1;
		}
		printf("[%s:%d]-连接成功newfd = %d\n",\
				inet_ntoa(cin.sin_addr),\
				ntohs(cin.sin_port),newfd);
		//客户端连接成功 创建子进程用于通信
		pid_t pid=fork();

		//判断父进程
		if(pid>0)
		{
			//父进程
			//不需要用到newfd,关闭
			close(newfd);
		}
		else if(pid ==0)
		{
			//用不到sfd,关闭
			close(sfd);
			//5.实现数据的的收发
			char buf[128]="";
			while(1)
			{
				//清空buf
				bzero(buf,sizeof(buf));

				//从套接字 中 读取消息
				int res = recv(newfd,buf,sizeof(buf),0);
				if(res==0)
				{
					printf("客户端已下线\n");
					close(newfd);
					break;
				}
				printf("[%s:%d]:%s\n",\
						inet_ntoa(cin.sin_addr),\
						ntohs(cin.sin_port),buf);
				//给消息加一个:D还回去
				strcat(buf,":D");
				send(newfd,buf,strlen(buf),0);
				printf("发送成功\n");
			}


		}
	}
	//6.关闭套接字
	close(sfd);
	return 0;
}

TCP多线程并发服务器

网络编程实现,一个服务器,一个客户端的通信;多线程并发;线程分离,系统自动回收子线程的资源

代码

复制代码
#include<myhead.h>
#define SER_IP "172.20.10.3" //服务器ip地址 虚拟机的
#define SER_PORT 8888

/****************main function***************/
int main()
{
	//1.创建一个用于连接的 套接字描述符
	int sfd = socket(AF_INET,SOCK_STREAM,0);
	if (sfd == -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("setsockopr error");
		return -1;
	}
	printf("端口已快速重用\n");

	//2.给套接字绑定ip地址和端口号
	//2.1 准备地址信息结构体
	struct sockaddr_in sin;
	sin.sin_family = AF_INET;//通信域地址族
	sin.sin_port = htons(SER_PORT);//服务器端口号
	sin.sin_addr.s_addr = inet_addr(SER_IP);
	//2.2 执行绑定工作
	if(bind(sfd,(struct sockaddr*)&sin,sizeof(sin))==-1)
	{
		perror("bind error");
		return -1;
	}
	printf("bind success");

	//3.将套接字 设置 被动监听状态
	if(listen(sfd,128)==-1)
	{
		perror("listen error");
		return -1;
	}
	printf("listen success\n");

	//4.阻塞等候 客户端的连接
	//4.1定义地址信息结构体,用于接收客户端地址信息
	struct sockaddr_in cin;
	socklen_t addrlen=sizeof(cin); //接收地址长度
	while(1)
	{
		int newfd = accept(sfd,(struct sockaddr*)&cin,&addrlen);
		if(newfd ==-1)
		{
			perror("accept error");
			return -1;
		}
		printf("[%s:%d]-连接成功newfd = %d\n",\
				inet_ntoa(cin.sin_addr),\
				ntohs(cin.sin_port),newfd);
		//5.实现数据的的收发
		char buf[128]="";
		while(1)
		{
			//清空buf
			bzero(buf,sizeof(buf));

			//从套接字 中 读取消息
			int res = recv(newfd,buf,sizeof(buf),0);
			if(res==0)
			{
				printf("客户端已下线\n");
				close(newfd);
				break;
			}
			printf("[%s:%d]:%s\n",\
					inet_ntoa(cin.sin_addr),\
					ntohs(cin.sin_port),buf);
			//给消息加一个:D还回去
			strcat(buf,":D");
			send(newfd,buf,strlen(buf),0);
			printf("发送成功\n");
		}
		//6.关闭套接字
		close(sfd);
		return 0;
	}
}

基于UDP的网络聊天室

没写出来,下一篇补充一下吧。 (╥﹏╥)

相关推荐
HABuo13 小时前
【Linux进程(四)】进程切换&环境变量深入剖析
linux·运维·服务器·c语言·c++·ubuntu·centos
橘颂TA13 小时前
【Linux】死锁四条件的底层逻辑:从锁冲突到 STL 组件的线程安全实践(Ⅵ)
linux·运维·服务器·c++·死锁
运维栈记13 小时前
虚拟化网络的根基-网络命名空间
网络·docker·容器
五仁火烧14 小时前
生产环境中配置了接口3000后,不能启动,改成8080后就可以
linux·网络·安全·vue
橙露14 小时前
国产PLC与进口PLC全面对比分析:技术、市场与未来趋势
运维·网络
清水白石00814 小时前
解构异步编程的两种哲学:从 asyncio 到 Trio,理解 Nursery 的魔力
运维·服务器·数据库·python
chilavert31815 小时前
技术演进中的开发沉思-302计算机原理:网络基础
网络·计算机原理
Hellc00715 小时前
Docker网络冲突排查与解决方案:完整指南
网络·docker·容器
代码游侠15 小时前
应用——智能配电箱监控系统
linux·服务器·数据库·笔记·算法·sqlite
眠りたいです15 小时前
Docker核心技术和实现原理第二部分:docker镜像与网络原理
运维·网络·docker·容器