TCP并发服务器的简易程序

libuv搭建高并发tcp服务器 采用libuv搭建高并发tcp服务器,对于没有使用libuv经验,或者无并发服务器编写经验的朋友还是有一定难度的,通常面对的问题如下(以linux环境为前提): 1,并发服务器采用什么样的服务器模型?epoll?poll?还是select? 2,选择什么样的并发服务器框架?libevent?libev?还是libuv? 3,如果使用libuv作为服务器框架,其基础框架如何搭建 4,libuv对新手并不友好,尤其是处处回调,何时申请内存,何时释放内存?新手经常碰到内存释放不正确导致程序coredump 5,l 阅读详情

1.服务器采用简易线程开启,将传送过来的字母转换为大写再发送过去,如果传送过来的第一个字符为@则退出

2.客户端循环读入,如果输入@则退出当前socket

 服务器程序:server_thread.c

#include<stdlib.h>
#include<stdio.h>
#include<errno.h>
#include<string.h>
#include<netdb.h>
#include<sys/types.h>
#include<sys/socket.h>
#include<netinet/in.h>
#include<unistd.h>
#include<sys/un.h>
#include<sys/wait.h>
#include<signal.h>
#include<pthread.h>


void* thr_fn(void* arg)
{
	int n_read;
	char sz_buff[1024];
	int n_newfd = *((int*)arg);
	int j;
	printf("new socket: %d\n",n_newfd);
	
	//从客户端读取数据
	while( ( n_read=read(n_newfd,sz_buff,1024) ) > 0 )
	{
		if(sz_buff[0]=='@')
		{
			printf("socket(%d) out ...\n", n_newfd);
			close(n_newfd);
			break;
		}
		printf("read %d byte data from client:%s",n_read,sz_buff);
		
		//将读取的数据全部转换为大写
		for(j=0; j<n_read; j++)
		{
			sz_buff[j]=toupper(sz_buff[j]);
		}	
		//将转换后的字符串再发送出去
		if(write(n_newfd,sz_buff,n_read)==-1)
		{
			fprintf(stderr,"write data  error: %s\n", strerror(errno));
			exit(1);
		}
		memset(sz_buff,0,1024);
	}
	close(n_newfd);
	
	return 0;
}
	
		

int main(int argc,char* argv[])
{
	
	int n_sockfd, n_newfd;
	struct sockaddr_in st_server;
	struct sockaddr_in st_client;
	
	int n_client_size,n_read_size;
	socklen_t n_addr_len;	
	
	int n_port;
	char sz_buff[1024];
	pthread_t pid;
	
	if(argc != 2)
	{
		printf("please input argument\n");
		exit(1);
	}
	
	if( (n_sockfd=socket(PF_INET,SOCK_STREAM,0))==-1)
	{
		fprintf(stderr,"scoket error:%s\n",strerror(errno));
		exit(1);
	}
	
	//bzero(&st_server,sizeof(st_server));
	memset(&st_server,0,sizeof(st_server));
	st_server.sin_family=AF_INET;
	st_server.sin_addr.s_addr=htonl(INADDR_ANY);
	st_server.sin_port=htons( atoi(argv[1]) );
	
	if(bind(n_sockfd,(struct sockaddr*)&st_server,sizeof(st_server))==-1)
	{
		fprintf(stderr,"bind server error:%s\n\a",strerror(errno));
		close(n_sockfd);
		exit(1);
	}
	
	if(listen(n_sockfd,2)==-1)
	{
		fprintf(stderr,"listen error:%s\n\a",strerror(errno));
		close(n_sockfd);
		exit(1);
	}
	
	while(1)
	{
		n_client_size=sizeof(st_client);
		if( (n_newfd=accept(n_sockfd,(struct sockaddr*)&st_client,&n_client_size))==-1)
		{
			if(errno==EINTR)
			{
				continue;
			}
			fprintf(stderr,"accept error:%s\n\a",strerror(errno));
			close(n_sockfd);
			exit(1);
		}
		fprintf(stderr,"server get connet from:%s\n",inet_ntoa(st_client.sin_addr));
		printf("new socket: %d\n",n_newfd);
		
		//创建线程
		if( (pthread_create(&pid,NULL,thr_fn,&n_newfd))==-1)
		{
			fprintf(stderr,"create thread error:%s\n",strerror(errno));			
			close(n_newfd);
			close(n_sockfd);
			exit(1);
		}
	}
	//close(n_sockfd);
	exit(0);	
}
	


 
客户端程序:client_thread.c

#include<stdlib.h>
#include<stdio.h>
#include<errno.h>
#include<string.h>
#include<netdb.h>
#include<sys/types.h>
#include<sys/socket.h>
#include<netinet/in.h>
#include<sys/un.h>
#include<unistd.h>

#define PORT_NUM 3333

int main(int argc,char*argv[])
{
	int n_sockfd;
	struct sockaddr_in st_server;
	char sz_buff[1024];
	struct hostent* pst_host;
	int n_port;
	int n_read;
	
	if(argc != 3)
	{
		fprintf(stderr,"please input argument\n");
		exit(1);
	}
	
	/*
	if( (pst_host=gethostbyname(argv[1]))==NULL)
	{
		fprintf(stderr,"gethostname error:%s\n",strerror(errno));
		exit(1); 
	}
	*/
	
	
	if( (n_sockfd=socket(PF_INET,SOCK_STREAM,0))==-1)
	{
		fprintf(stderr,"scoket error:%s\n",strerror(errno));
		exit(1);
	}
	
	//bzero(&st_server,sizeof(st_server));
	memset(&st_server,0,sizeof(st_server));
	st_server.sin_family=AF_INET;
	//st_server.sin_addr=*((struct in_addr*)pst_host->h_addr);
	//pst_host 是一个指针指向in_addr*类型的数组
	st_server.sin_addr.s_addr=inet_addr(argv[1]);
	st_server.sin_port=htons(atoi(argv[2]));
	
	if(connect(n_sockfd,(struct sockaddr*)&st_server,sizeof(st_server))==-1)
	{
		fprintf(stderr,"connect server error:%s\n\a",strerror(errno));
		close(n_sockfd);
		exit(1);
	}
	
	while(1)
	{	
		  //输入数据提示
			if( write(STDOUT_FILENO,"\nplease input data:",20)==-1)
			{
				fprintf(stderr,"write error:%s\n",strerror(errno));
				exit(1);
			}
			
			//读取输入的数据,并发送给服务器
			memset(sz_buff,0,1024);
			n_read=read(STDIN_FILENO,sz_buff,1024);			
			printf("n_read = %d,send message: %s",n_read,sz_buff);
			
			if(n_read>0)
			{			
				if( write(n_sockfd,sz_buff,n_read)==-1)
				{
					fprintf(stderr,"write error:%s\n",strerror(errno));
					exit(1);
				}
			}
			
			//如果读取的第一个数据位@则推出循环
			if( sz_buff[0]=='@' )
			{
				break;
			}
			
			//从服务器读取数据
			memset(sz_buff,0,1024);
			printf("n_sockfd = %d\n",n_sockfd);
			n_read=read(n_sockfd,sz_buff,n_read);
			printf("read message: %s",sz_buff);
			if(n_read>0)
			{
				printf("get message from server: %s",sz_buff);
			}
	}
	close(n_sockfd);
	
	exit(0);	
}
	

调式结果:


注:切记不要在服务器段提前关闭socket,服务器监听套接字不能关闭,一直处于循环等待中

       一旦客户端关闭socket,就不能再发送数据了

TCP并发服务器设计 TCP并发服务器是通过创建子进程来处理不同客户端的请求实现的 server.c /* ** TCP并发服务器 */ #include #include #include #include #include #include #include #include #define portnumber 3333 int main( int argc, cha 阅读详情

相关推荐

TCP网络通信(多线程客户端和服务器端)

比较牛逼的代码 ,多线程,服务器和客户端可以同时相互接受和发送数据。 另外还有详细的Linux 网络编程资料

网络编程【TCP编程流程&&多进程/多线程处理并发访问】

TCP提供的是面向连接的、可靠的、字节流服务。

qq_43475751的博客 598

vivado Block Design 设计 .tcl 文件使用,导出,修改,添加方式

在vivado中生成 Block Design可以导出tcl文件进行保存(体积小),或者在别的版本vivado中打开(版本互通),这是一个非常好的功能。另外GitHub中很多项目都是采用这种方式上传的,学会如何使用可以快速修改历程项目。

2203_75345038的博客 2494

实现TCP并发服务器

详解实现TCP并发服务器两种方法:1、使用多进程实现TCP并发服务器2、使用多线程实现TCP并发服务器。

weixin_47783699的博客 3069

Win10家庭版如何添加本地用户和组

在众多Windows版本中,Windows 10以其丰富的功能和卓越的性能吸引了大量用户。然而,对于使用Win10家庭版的用户来说,他们可能会遇到一些功能上的限制,特别是在用户和组管理方面。虽然家庭版在某些高级功能上有所缩减,但我们仍然可以通过一些技巧来实现对本地用户和组的管理。本文将详细介绍如何在Win10家庭版中添加本地用户和组,以便用户能够更好地管理计算机资源。

nntxthml的博客 4558

PTC-6-2004汽轮机性能计算源代码,pycharm-包括试验计算、一类修正、二类修正-以CC350-16.7/0.98/0.5/538/538型汽轮机为例,5万7千字,过程不易欢迎打赏

汽轮机性能计算完整源代码-简化试验-包括试验计算一类修正计算和二类修正计算目录图 1 工程结构。

weixin_43441028的博客 1001

TCP 通信并发服务器详解(附有案例代码)

代码】TCP通信并发详解(附有案例代码)

热爱数据库的小胖 2960

安装部署 Guacamole 远程桌面网关

Guacamole 是Apache基金会提供的一组基于web的远程桌面访问工具,支持 VNC、RDP、SSH、 Telnet 等协议,支持远程透传音视频。

UsamaBinLaden6976498的专栏 1964

服务器模型:循环服务器(TCP)和并发服务器(TCP)

服务器模型:循环服务器(TCP)和并发服务器(TCP)搭建

weixin_57723364的博客 2211

深入理解Android音视频同步机制(三)NuPlayer的avsync逻辑

本文深入介绍了NuPlayer的avsync逻辑和原理

张晖的专栏 1万+

【1.2】Costas环的基本原理概述

Costas环是一种用于载波恢复的相干解调技术,可直接从BPSK等抑制载波信号中恢复本地载波并完成解调。其核心结构包含同相/正交双支路处理,通过混频、低通滤波后,利用I/Q支路信号乘积进行相位误差检测,经环路滤波器调节VCO输出频率,实现载波同步。课程将重点讲解Costas环的MATLAB仿真实现、系统性能分析及FPGA开发,包括信号产生、频偏模拟、滤波器设计等模块,并通过AWGN信道和不同频偏条件下的测试验证系统性能。该技术无需单独提取载波,在数字通信系统中具有重要应用价值。

fpga/matlab/simulink算法仿真工程 452

无线多路并发服务器,六、TCP详解和并发服务器

1.TCP下图是基于TCP协议的客户端/服务器程序的一般流程:TCP协议通讯流程服务器调用socket()、bind()、listen()完成初始化后,调用accept()阻塞等待,处于监听端口的状态,客户端调用socket()初始化后,调用connect()发出SYN段并阻塞等待服务器应答,服务器应答一个SYN-ACK段,客户端收到后从connect()返回,同时应答一个ACK段,服务器收到后从...

weixin_39646628的博客 587

激光雷达与相机外参标定(附open3d python代码)

现在的激光雷达与相机的标定程序基本都是Ubuntu框架下面的,并且都是C++代码,需要安装的依赖也比较复杂,于是自己写了一个python版本的标定程序,依赖非常简单,Windows系统也可以运行。我这里用的大疆的雷达,点比较密集,更容易用我这种方法标定,旋转的16,32线的雷达也可以用这种方法标定,只是标定点会相对难选取一些。2 手动在点云上选取N个标定点(每个点都对应图像上的点,顺序也要一致)3 通过PNP方法计算出二者的旋转投影矩阵,也就是外参矩阵。1 手动在图像上面选取N个标定点。

三维点云技术探索 3412

TCP并发服务器

UDP:单循环服务器,服务器同一时刻只能响应一个客户端的请求TCP:并发服务器,服务器同一时刻只能响应多个客户端的请求。

2401_84313943的博客 1157

Python爬虫实战:实时爬取东方财富网股票行情

东方财富网实时行情(价格、涨跌幅、成交量等)K线图、分时图、技术指标市盈率、换手率、总市值等指标相比某些收费API,东方财富网页端接口不需要登录、免费、响应快、封装清晰,适合爬虫实践。东方财富网股票数据接口分析实时数据抓取与字段提取数据结构化处理自动化批量抓取多线程加速采集数据可视化展示支持存储为CSV/Excel/数据库。

2201_76125261的博客 1万+

LinePhone3.2.7(android端最新版本) sip客户端

SIP客户端For android:LinePhone3.2.7(最新版本),官网地址:http://www.linphone.org/

网络编程day4——TCP循环服务器模型与并发服务器模型

只有在当前客户的所有请求都完成后,服务器才能处理下一个客户的连接/服务请求。关键是在某个客户端产生通信套接字后,在recv/send部分用一个while循环,直到此客户端完全结束通讯任务,才会产生新的通信套接字继续通信。并发服务器的设计思想是服务器接受客户端的连接请求后创建子进程来为客户端服务。: 大规模的 Web 服务器(如 Apache)、数据库服务器、在线游戏服务器等,需要处理大量并发连接的应用。TCP服务器接受一个客户端的连接后开始处理,完成了客户的所有请求后断开连接。

weixin_54481049的博客 1923

efm32 入门.pdf

本PDF共计22页,介绍的是操作驱动API,下载与否自己斟酌。

TCP并发

单循环服务器:服务端同一时刻只能处理一个客户端的任务并发服务器:服务端同一时刻可以处理多个服务端的任务。

weixin_75226106的博客 1924

IDEA的使用指南

IDEA基于java的使用手册,可以最快速的上手,在使用中不断的丰富自己的使用技巧.

IEM模型,地表粗糙度模拟

利用微波反演土壤水分时候,利用IEM模型可以实现对随机地表的模拟

TCP并发服务器的编程实现

TCP并发服务器的编程实现 1. 基于TCP的服务器编程模型 创建通信端点(套接字),返回该端点的文件描述符 sfd socket(2) 2 )将sfd和本地的ip地址和端口号绑定 bind(2); 3 )将sfd设置为被动连接状态,监听客户端的到来,如果有客户段的到来,将其放入到未决连接队列中.listen(2) while{ 4 从未决连接中取出一个处理,返回一个新的连接描述符 如果未决连接为空,阻塞等待 cfd = accept(2) 5 从连接描述符中读取客户段的请求数据到buf中 read(2)

figting 6572

实现百万并发的TCP服务器

本文介绍了如何优化TCP服务器以实现百万并发连接。首先测试了基于epoll的TCP服务器性能,发现存在两个主要问题:1) 默认每个进程的文件描述符限制为1024,通过修改系统参数提升至1048576;2) 客户端端口耗尽问题,通过服务器开启100个监听端口解决。文章提供了修改系统配置的方法和优化后的服务器代码,通过多端口监听方式显著提升了并发处理能力。测试结果表明,这些优化措施能够有效支持更高并发的TCP连接需求。

qq_51632182的博客 1178

嵌入式LINUX——————TCP并发服务器

底层对于集合表的方式改变,变成了链表,时间复杂度O(n),其他问题未被改善,仍然需要反复拷贝、遍历、只可工作在水平触发模式;水平触发:数据从无到有,先触发一次读,没读完,再触发读,一直到读完了,才不触发;边沿触发:数据从无变有,从低电平到高电平,触发一次,称读数据的上升沿触发;select只能工作在水平触发模式(低速模式),不能工作在边沿触发模式(高速模式);3)通过函数接口,把集合传递给内核,并开始检测IO事件(输入输出、读写事件);在应用层每次需要遍历才可找到到达的事件的文件描述符,效率不高,还耗时;

wxy319的博客 922

【C++高并发服务器WebServer】-12:TCP详解及实现

欢迎来到Golinie的频道,这里是C++并发服务器专题。本篇文章主要围绕TCP通信展开,详细介绍了TCP通信流程以及关键的套接字函数,包括socket()、bind()、listen()、accept()和connect()。同时,通过server端和client端的代码示例,展示了并发服务器的实现过程。此外,还深入探讨了TCP三次握手、滑动窗口机制以及四次挥手过程,最后介绍了多进程并发服务器的设计思路。

theaipower的博客 1万+

简单实现Tcp服务器的百万并发

1.准备好4个虚拟机一个 4G内存,2核cpu 作为Server端三个 2G内存,1核cpu 作为Client端。

qq_56877339的博客 1174

tcp并发服务器_在Go中构建并发TCP服务器

tcp并发服务器 本文是Mihalis Tsoukalos的“围棋”系列的一部分。 阅读第1部分: 在Go中创建随机,安全的密码 。 TCP和UDP服务器无处不在,通过TCP / IP网络为网络客户端提供服务。 在本文中,我将解释如何使用Go编程语言开发并发TCP服务器,该服务器返回随机数。 对于来自TCP客户端的每个传入连接,TCP服务器将启动一个新的goroutine来处理该请求。 ...

cuml0912的博客 575
上一篇: 再谈sizeof——struct 结构存储空间的大小:与成员的顺序、#progma pack参数有关系
下一篇: Win 7 64 Mini2440 使用ADS1.2配置步骤和问题解决方法
comwise
博客等级 码龄15年 58粉丝 85原创
评论
成就一亿技术人!
拼手气红包6.0元
还能输入1000个字符
 
 条评论被折叠 查看
添加红包

请填写红包祝福语或标题

个

红包个数最小为10个

元

红包金额最低5元

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

抵扣说明:

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

余额充值