linux网络编程的服务端和客户端实战的基本实现

网络编程的服务端和客户端实战的基本实现

1.编写服务端和客户端基本流程图

在这里插入图片描述

2. 服务端代码实现和解析

1)服务端的流程
代码实现一般分为六个流程

1 socket,套接字

我们要创建套接字,为套接字添加信息
socket()

我们一般使用的AF_INET IPV4因特网域,在国内一般是使用AF_INET,TYPE参数一般也是使用TCP协议的SOCK_STREAM

 s_fd = socket(AF_INET,SOCK_STREAM,0);

套接字输入信息

          s_addr.sin_family = AF_INET;
          s_addr.sin_port = htons(atoi(argv[2]));
          inet_aton(argv[1],&s_addr.sin_addr);

地址转换API


int inet_aton(const char* straddr,struct in_addr *addrp);
把字符串形式的“192.168.1.123”转为网络能识别的格式

char* inet_ntoa(struct in_addr inaddr); 
把网络格式的ip地址转为字符串形式

2 bind
在这里插入图片描述
在这里插入图片描述
我们一般使用是的 struct sockaddr_in 所以在bind()函数里,我们要强转成struct sockaddr

 bind(s_fd,(struct sockaddr *)&s_addr,sizeof(struct sockaddr_in));

3 linsten
4 accept
5 read
6 write

服务器的代码

#include <stdio.h>
#include <sys/types.h>          /* See NOTES */
#include <sys/socket.h>
//#include <linux/in.h>
#include <arpa/inet.h>
#include <netinet/in.h>
#include <stdlib.h>
#include <string.h>

int main(int argc,char **argv)
{
	// 1 socket
	printf("aaa");
	socklen_t s_fd;
	int c_fd;
	int size;
	int n_read;
	char readBuff[128] = {0};
	//	char *servemsg = "I recieve\n";
	char servemsg[128] = {0};
	struct sockaddr_in s_addr;
	struct sockaddr_in c_addr;
	memset(&s_addr,0,sizeof(struct sockaddr_in));
	memset(&c_addr,0,sizeof(struct sockaddr_in));
	s_fd = socket(AF_INET,SOCK_STREAM,0);
	if(s_fd == -1){
		perror("socket");
		exit(-1);
	}
	// 2 bind
	s_addr.sin_family = AF_INET;
	s_addr.sin_port = htons(atoi(argv[2]));
	inet_aton(argv[1],&s_addr.sin_addr);
	bind(s_fd,(struct sockaddr *)&s_addr,sizeof(struct sockaddr_in));
	// 3 listen
	listen(s_fd,10);
	// 4 accept
	while(1){
		size = sizeof(struct sockaddr_in);
		c_fd = accept(s_fd,(struct sockaddr *)&c_addr,&size);
		if(c_fd == -1){
			perror("accpect");
		}
		printf("get connect %s\n",inet_ntoa(c_addr.sin_addr));
		// 5 read
		if(fork() == 0){
			if(fork() == 0){
				while(1){
					memset(servemsg,0,128);
					printf("input\n");
					gets(servemsg);
					write(c_fd,servemsg,strlen(servemsg));
				}
			}
			while(1){
				memset(readBuff,0,128);
				n_read = read(c_fd,readBuff,128);
				if(n_read == -1){
					perror("read");
				}else{
					printf("get msg:%d,%s\n",n_read,readBuff);
				}
			}
		}
		// 6 write 
	}
	//	while(1);
	return 0;
}


3 客户端代码

#include <stdio.h>
#include <sys/types.h>          /* See NOTES */
#include <sys/socket.h>
//#include <linux/in.h>
#include <arpa/inet.h>
#include <netinet/in.h>
#include <stdlib.h>
#include <string.h>

int main(int argc,char **argv)
{
	// 1 socket
	int c_fd;
	int size;
	int n_read;
	char readBuff[128] = {0};
	char *clientmsg = "msg from client\n";
	struct sockaddr_in c_addr;
	memset(&c_addr,0,sizeof(struct sockaddr_in));
	c_fd = socket(AF_INET,SOCK_STREAM,0);
	if(c_fd == -1){
		perror("socket");
		exit(-1);
	}
	// 2 bind
	c_addr.sin_family = AF_INET;
	c_addr.sin_port = htons(atoi(argv[2]));
	inet_aton(argv[1],&c_addr.sin_addr);
	connect(c_fd,(struct sockaddr *)&c_addr,sizeof(struct sockaddr_in));
	// 5 read
	write(c_fd,clientmsg,strlen(clientmsg));
	n_read = read(c_fd,readBuff,128);
	if(n_read == -1){
		perror("read");
	}else{
		printf("get msg from serve:%d,%s",n_read,readBuff);
	}
	
	// 6 write 
	return 0;
}

这是一门linux下c++通讯架构实战课程,针对c/c++语言已经掌握的很熟并希望进一步深造以将来用c++在linux下从事网络通讯领域/网络服务器的开发和架构工作。这门课程学习难度颇高但也有着极其优渥的薪水(最少30K月薪,最高可达60-80K月薪),这门课程,会先从nginx源码的分析和讲解开始,逐步开始书写属于自己的高性能服务器框架代码,完善个人代码库,这些,将会是您日后能取得高薪的重要筹码。本课程原计划带着大家逐行写代码,但因为代码实在过于复杂和精细,带着写代码可能会造成每节课至少要4~5小时的超长时间,所以老师会在课前先写好代码,主要的时间花费在逐行讲解这些代码上,这一点望同学们周知。如果你觉得非要老师领着写代码才行的话,老师会觉得你当前可能学习本门课程会比较吃力,请不要购买本课程,以免听不懂课程并给老师差评,差评也会非常影响老师课程的销售并造成其他同学的误解。 这门课程要求您具备下面的技能:(1)对c/c++语言掌握的非常熟练,语言本身已经不是继续学习的障碍,并不要求您一定熟悉网络或者linux;(2)对网络通讯架构领域有兴趣、勇于挑战这个高难度的开发领域并期望用大量的付出换取高薪;在这门课程中,实现了一个完整的项目,其中包括通讯框架和业务逻辑框架,浓缩总结起来包括如下几点:(1)项目本身是一个极完整的多线程高并发的服务器程序;(2)按照包头包体格式正确的接收客户端发送过来的数据包, 完美解决收包时的数据粘包问题;(3)根据收到的包的不同来执行不同的业务处理逻辑;(4)把业务处理产生的结果数据包正确返回给客户端;本项目用到的主要开发技术和特色包括:(1)epoll高并发通讯技术,用到的触发模式是epoll中的水平触发模式【LT】;(2)自己写了一套线程池来处理业务逻辑,调用适当的业务逻辑处理函数处理业务并返回给客户端处理结果;(3)线程之间的同步技术包括互斥量,信号量等等;(4)连接池中连接的延迟回收技术,这是整个项目中的精华技术,极大程度上消除诸多导致服务器程序工作不稳定的因素;(5)专门处理数据发送的一整套数据发送逻辑以及对应的发送线程;(6)其他次要技术,包括信号、日志打印、fork()子进程、守护进程等等;
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值