课设:回声服务器和计算器(详细可运行代码)

一.回声服务

#include 
#include
#include     //memset
#include  //htos
#include  //socket
#include //struct sockaddr
#include  //close
#include

void ser() //服务端
{
	//第一步建立套接字
	int ser_sk = socket(PF_INET, SOCK_STREAM, 0);

	//第二步建立地址信息,并用bind进行绑定
	struct sockaddr_in ser_add;				   //建立服务端套接字地址结构
	memset(&ser_add, 0, sizeof ser_add);
	ser_add.sin_family = AF_INET;				   //填写对应的port,ip,协议族
	ser_add.sin_port = htons(9100);
	ser_add.sin_addr.s_addr = htonl(INADDR_ANY);   //记得转换为网络字节序
	bind(ser_sk, (struct sockaddr*)&ser_add, sizeof ser_add);  //绑定IP,port


	//第三步监听套接字,创建连接队列
	listen(ser_sk, 5);

	//第四步进行accpet连接通信
	char buffer[1500] = "";
	char ip[16] = "";
	unsigned short port = 0;

	for (int i = 0; i < 2; i++) {
		memset(buffer, 0, sizeof buffer);
		memset(ip, 0, sizeof ip);
		struct sockaddr_in cli_add;
		socklen_t cli_len = sizeof cli_add; 

		int ser_acsk = accept(ser_sk, (struct sockaddr*)&cli_add, &cli_len);  //建立连接,获得通信套接字,和对方套接字信息

		if (ser_acsk == -1) {
			printf("accept failed !\n");
			close(ser_sk);
			return;
		}
		//接受信息
		

		inet_ntop(AF_INET, &cli_add.sin_addr.s_addr, ip, 16); //把32为ip地址转化为字符串
		port = ntohs(cli_add.sin_port);  //网络字节序转化为主机字节序
		printf("客户端 : %s %d  connnected\n", ip, port);
		int  len = 0;
		while (( len = recv(ser_acsk, buffer, sizeof buffer, 0)) > 0) //接受信息
		{
			send(ser_acsk, buffer, len , 0 );
			memset(buffer, 0, sizeof buffer);
		}
	
		close(ser_acsk);
	}
	printf("ser done!\n");
	close(ser_sk);
}


void cli()    //客户端
{
	//第一步:建立套接字
	int cli_sk = socket(PF_INET, SOCK_STREAM, 0);  //建立客户端套接字

	//第二步建立发送到的地址结构
	struct sockaddr_in ser_add;
	memset(&ser_add, 0, sizeof ser_add);

	ser_add.sin_family = AF_INET;
	ser_add.sin_addr.s_addr = inet_addr("127.0.0.1");
	ser_add.sin_port = htons(9100);

	//第三步骤建立连接,给客户端分配端口
	int ret = connect(cli_sk, (struct sockaddr*)&ser_add, sizeof ser_add);

	while (ret == 0) {
	//第四步发送信息
		char buffer[256] = "";
		fputs("Input message(Q to quit):", stdout);  //输出提示信息
		fgets(buffer, sizeof buffer, stdin);  //从标准输入流里面读取信息
		if ((strcmp(buffer, "q\n") == 0) || (strcmp(buffer, "Q\n") == 0))
		{
			break;
		}

		//一个包只能发1K出头的字节数,避免一次发不完
		size_t len = strlen(buffer);  //发送消息的长度
		size_t send_len = 0; //已发送的长度
		while (send_len < len) {
			ssize_t num = send(cli_sk, buffer + send_len, len - send_len, 0);  //发送给服务器
			if (num < 0) {
				fputs("write failed!\n", stdout);
				close(cli_sk);
				printf("client done!\n");
				return;
			}
			send_len += num;
		}
		
		memset(buffer, 0, sizeof buffer);    
		size_t read_len = 0; //已读取的长度
		while (read_len < len) {
			ssize_t num = recv(cli_sk, buffer + read_len, len - read_len, 0);  //接受信息
			if (num < 0) {
				fputs("read failed!\n", stdout);
				close(cli_sk);
				printf("client done!\n");
				return;
			}
			read_len += num;
		}
		
		printf("from server :%s\n", buffer);
	}
	
	close(cli_sk);
}

void pra() {

	pid_t pid = fork();
	if (pid == 0)
	{
		//开启服务端
		ser();
	}
	else if (pid > 0) {
		sleep(1);
		for (int i = 0; i < 2; i++) {
			cli();
		}
		int status = 0;
		wait(&status);
	}

}

int main() {

	pra();
	return 0;
}

代码运行

课设:回声服务器和计算器(详细可运行代码)_第1张图片

 二.计算器

#include 
#include
#include     //memset
#include  //htos
#include  //socket
#include //struct sockaddr
#include  //close
#include

int calulate(int count, int oprand[], char op)
{
	int res = 0;
	switch (op)
	{

	case '+':
		for (int i = 0; i < count; i++) {
			res += oprand[i];
		}
		break;
	case '-':
		for (int i = 0; i < count; i++) {
			if (i == 0) res = oprand[0];
			else res -= oprand[i];
		}
		break;
	case '*':
		res = 1;
		for (int i = 0; i < count; i++) {
			res *= oprand[i];
		}
		break;



	default:
		break;
	}

	return res;
}

void ser() //服务端
{
	//第一步建立套接字
	int ser_sk = socket(PF_INET, SOCK_STREAM, 0);

	//第二步建立地址信息,并用bind进行绑定
	struct sockaddr_in ser_add;				   //建立服务端套接字地址结构
	memset(&ser_add, 0, sizeof ser_add);
	ser_add.sin_family = AF_INET;				   //填写对应的port,ip,协议族
	ser_add.sin_port = htons(9100);
	ser_add.sin_addr.s_addr = htonl(INADDR_ANY);   //记得转换为网络字节序
	bind(ser_sk, (struct sockaddr*)&ser_add, sizeof ser_add);  //绑定IP,port


	//第三步监听套接字,创建连接队列
	listen(ser_sk, 5);

	//第四步进行accpet连接通信
	char buffer[1500] = "";
	char ip[16] = "";
	unsigned short port = 0;

	for (int i = 0; i < 2; i++) {
		memset(buffer, 0, sizeof buffer);
		memset(ip, 0, sizeof ip);
		struct sockaddr_in cli_add;
		socklen_t cli_len = sizeof cli_add;

		int ser_acsk = accept(ser_sk, (struct sockaddr*)&cli_add, &cli_len);  //建立连接,获得通信套接字,和对方套接字信息

		if (ser_acsk == -1) {
			printf("accept failed !\n");
			close(ser_sk);
			return;
		}
		//接受信息


		inet_ntop(AF_INET, &cli_add.sin_addr.s_addr, ip, 16); //把32为ip地址转化为字符串
		port = ntohs(cli_add.sin_port);  //网络字节序转化为主机字节序
		printf("客户端 : %s %d  connnected\n", ip, port);
		int  len = 0;
		while ((len = recv(ser_acsk, buffer, sizeof buffer, 0)) > 0) //接受信息
		{
			int op_num = (int)buffer[0] & 0xFF;
			int ans = calulate(op_num, (int*)(buffer + 1), buffer[op_num * sizeof(int) + 1]);
			send(ser_acsk, &ans, sizeof(int), 0);
			memset(buffer, 0, sizeof buffer);
		}

		close(ser_acsk);
	}
	printf("ser done!\n");
	close(ser_sk);
}


void cli()    //客户端
{
	//第一步:建立套接字
	int cli_sk = socket(PF_INET, SOCK_STREAM, 0);  //建立客户端套接字

	//第二步建立发送到的地址结构
	struct sockaddr_in ser_add;
	memset(&ser_add, 0, sizeof ser_add);

	ser_add.sin_family = AF_INET;
	ser_add.sin_addr.s_addr = inet_addr("127.0.0.1");
	ser_add.sin_port = htons(9100);

	//第三步骤建立连接,给客户端分配端口
	int ret = connect(cli_sk, (struct sockaddr*)&ser_add, sizeof ser_add);

	while (ret == 0) {
		//第四步发送信息
		char buffer[256] = "";
		fputs("Input message(Q to quit):", stdout);  //输出提示信息
		std::cin >> buffer;
		if ((strcmp(buffer, "q") == 0) || (strcmp(buffer, "Q") == 0))
		{
			break;
		}

		memset(buffer, 0, sizeof buffer);
		fputs("Operand count:", stdout);  //输出提示信息 
		int op_cnt = 0;
		std::cin >> op_cnt;
		if (op_cnt <= 1 || op_cnt > 255) {
			fputs("Operand count error\n", stdout);
			close(cli_sk);
			printf("client done!\n");
			return;
		}
		buffer[0] = (char)op_cnt;
		for (int i = 0; i < op_cnt; i++) {
			std :: cin >> *(int*)(buffer + 1 + i * sizeof(int));

		}
		fputs("Operator:", stdout);
		std :: cin >> buffer[op_cnt * sizeof(int) + 1] ;
		printf("\n");

		//一个包只能发1K出头的字节数,避免一次发不完
		size_t len = strlen(buffer);  //发送消息的长度
		size_t send_len = 0; //已发送的长度

		ssize_t num = send(cli_sk, buffer, op_cnt * sizeof(int) + 2, 0);  //发送给服务器

		if (num <= 0) {
			fputs("send failed!\n", stdout);
			close(cli_sk);
			printf("client done!\n");
			return;
		}


		printf("send num : %d sleep\n", num);

		int ed_ans = -100;

		ssize_t re_num = recv(cli_sk, &ed_ans, sizeof(int), 0);  //接受信息
		if (re_num <= 0) {
			fputs("recv failed\n", stdout);
			close(cli_sk);
			printf("client done!\n");
			return;
		}

		printf("from server :%d\n", ed_ans);
		sleep(1);
	}

	close(cli_sk);
}

void pra() {

	pid_t pid = fork();
	if (pid == 0)
	{
		//开启服务端
		ser();
	}
	else if (pid > 0) {
		sleep(1);
		for (int i = 0; i < 2; i++) {
			cli();
		}
		int status = 0;
		wait(&status);
	}

}

int main() {

	pra();
	return 0;
}

课设:回声服务器和计算器(详细可运行代码)_第2张图片

 

你可能感兴趣的:(服务器,架构,网络)