基于tcp协议的计算器程序

客户端发送操作数个数,操作数,运算符到客户端,客户端计算后返回。同一时刻只服务一个客户端。

在字符数组中,操作数个数占第一个字节,紧接着每一个操作数占四个字节,最后运算符占一个字节。因为是不同类型,因此数组为char型

服务器:

 

#include "stdafx.h"
#include<WinSock2.h>
#include<string.h>
#include<stdlib.h>
#include<stdlib.h>

#define BUFF_SIZE 1024
#define OPSZ	  4

void Errorhanding(char* message){
	fputs(message, stderr);
	fputc('\n', stderr);
	exit(1);
}

int calculate(int opnum, int opnds[], char op)
{
	int result = opnds[0], i;

	switch (op)
	{
	case '+':
		for (i = 1; i < opnum; i++) result += opnds[i];
		break;
	case '-':
		for (i = 1; i < opnum; i++) result -= opnds[i];
		break;
	case '*':
		for (i = 1; i < opnum; i++) result *= opnds[i];
		break;
	}
	return result;
}

int _tmain(int argc, _TCHAR* argv[])
{
	WSADATA wsaData;
	SOCKET hServSock, hClntSock;
	char opinfo[BUFF_SIZE];
	int result, opndCnt, i;
	int recvCnt, recvLen;
	SOCKADDR_IN  servAdr, clntAdr;
	int clntAdrSize;

	if (WSAStartup(MAKEWORD(2, 2), &wsaData) != 0)
		Errorhanding("WSAStartup() error!\n");

	hServSock = socket(PF_INET, SOCK_STREAM, 0);
	if (hServSock == INVALID_SOCKET)
		Errorhanding("socket() error!\n");
	
	memset(&servAdr, 0, sizeof(servAdr));
	servAdr.sin_family = AF_INET;
	servAdr.sin_addr.S_un.S_addr = htonl(INADDR_ANY);
	servAdr.sin_port = htons(atoi("8888"));

	if (bind(hServSock, (SOCKADDR*)&servAdr, sizeof(servAdr)) == SOCKET_ERROR)
		Errorhanding("bind() error!\n");

	if (listen(hServSock, 5) == SOCKET_ERROR)
		Errorhanding("listen() error!\n");

	clntAdrSize = sizeof(clntAdr);

	for ( i = 0; i < 5; i++)
	{
		opndCnt = 0;
		hClntSock = accept(hServSock, (SOCKADDR*)&clntAdr, &clntAdrSize);

		recv(hClntSock, (char*)&opndCnt, 1, 0); //先接受操作数的个数

		recvLen = 0;
		while ((opndCnt*OPSZ + 1)>recvLen)//只要没有全部接受完,最后一个字节为运算符
		{
			recvCnt = recv(hClntSock, &opinfo[recvLen], BUFF_SIZE - 1, 0);
			recvLen += recvCnt;
		}

		result = calculate(opndCnt, (int*)opinfo, opinfo[recvLen - 1]);
		send(hClntSock, (char*)&result, sizeof(result), 0);
		closesocket(hClntSock);
	}
	closesocket(hServSock);
	WSACleanup();
	system("pause");
	return 0;
}


客户端:

 

 

#include "stdafx.h"
#include<WinSock2.h>
#include<stdlib.h>
#include<stdlib.h>
#include<string.h>

#define BUF_SIZE 1024  //定义传输数组的容量
#define Rlt_SIZE 4	   //定义结果的大小
#define OPSZ	 4	   //定义操作数的大小

void Errorhanding(char* message){
	fputs(message, stderr);
	fputc('\n', stderr);
	exit(1);
}

int _tmain(int argc, _TCHAR* argv[])
{
	WSADATA wsaData;
	SOCKET	hsocket;
	char	opmsg[BUF_SIZE];
	int result, opndCnt, i;
	SOCKADDR_IN	servAdr;

	if (WSAStartup(MAKEWORD(2, 2), &wsaData) != 0)
		Errorhanding("WSAStartup() error!\n");

	hsocket = socket(PF_INET, SOCK_STREAM, 0);
	if (hsocket == INVALID_SOCKET)
		Errorhanding("socket() error!\n");

	memset(&servAdr, 0, sizeof(servAdr));
	servAdr.sin_family = AF_INET;
	servAdr.sin_addr.S_un.S_addr = inet_addr("192.168.1.154");
	servAdr.sin_port = htons(atoi("8888"));

	if (connect(hsocket, (SOCKADDR*)&servAdr, sizeof(servAdr)))
		Errorhanding("connect() error!\n");
	else
		puts("Connecting...\n");

	fputs("Operand cout : ", stdout);//提示输入操作数个数
	scanf("%d", &opndCnt);
	opmsg[0] = (char)opndCnt;//转为一个字节存放操作数个数

	for ( i = 0; i < opndCnt; i++)
	{
		printf("Operand %d: ", i + 1);
		scanf("%d", (int*)&opmsg[i*OPSZ + 1]);//每四个字节存放一个操作数
	}

	fgetc(stdin);//这句不该省,因为下面scanf接受的是字符格式,前面最后一次的回车会被当成输入字符接受,如果下面接受的是int型,则可以省略
	fputs("Operator: ", stdout);
	scanf("%c", &opmsg[opndCnt*OPSZ + 1]);//最后一个字节存放运算符

	send(hsocket, opmsg, opndCnt*OPSZ + 2,0);
	recv(hsocket, (char*)&result, Rlt_SIZE, 0);//接受结果转换为int型

	printf("Operation result: %d", result);
	closesocket(hsocket);
	WSACleanup();
	system("pause");
	return 0;
}

 

 

 

 

 

### 回答1: 基于socket通信的简单计算器可以通过以下步骤实现: 1. 创建一个服务器程序,使用socket API建立一个TCP/IP连接,等待客户端连接。 2. 当客户端连接到服务器时,服务器接受客户端的请求,解析请求中的计算表达式。 3. 服务器计算表达式的结果,并将结果发送回客户端。 4. 客户端接收服务器发送的结果,并将结果显示在屏幕上。 5. 客户端可以继续发送计算请求,服务器将继续处理请求并返回结果。 需要注意的是,服务器和客户端之间的通信需要遵循一定的协议,以确保数据的正确传输和处理。同时,需要考虑安全性和错误处理等问题,以提高程序的稳定性和可靠性。 ### 回答2: 基于socket通信的简单计算器可以通过网络进行远程计算。其实现过程分为服务器和客户端两部分。 服务器端: 1.创建服务端socket,绑定IP和端口号 2.监听客户端的连接请求,接受客户端发送的数据 3.根据客户端发送的数据进行计算,将计算结果返回给客户端 客户端: 1.创建客户端socket,连接到服务端指定的IP和端口号 2.将需要进行计算的数据发送给服务端 3.等待服务端返回的计算结果并输出 具体实现中,可以将数据发送和接收的格式规定为字符串,如“2+3”,“5-4”,“7*8”,“10/2”等,服务器端根据接收到的数据进行解析计算,客户端则接收并输出服务器端返回的结果。 在实现过程中,需要注意数据的合法性和异常处理。例如除数为0、数据格式不正确等情况都需要进行处理。 通过基于socket通信的简单计算器的实现,我们可以深入理解socket通信的原理,并掌握socket编程的基本方法。同时,这也是一个简单而实用的网络应用程序,可以为我们的日常工作和学习带来方便。 ### 回答3: 基于socket通信的简单计算器的实现通常涉及两个主要的组件:客户端和服务器。客户端向服务器发送计算请求,服务器收到请求后执行相应的计算操作,然后将结果发送回客户端。 首先,我们需要创建一个服务器程序来接收和处理客户端的计算请求。服务器可以使用Python中的socket库来实现。使用socket库中的socket()函数创建一个新的socket对象,并设置socket类型和地址族。在此之后,就可以使用bind()函数将socket绑定到一个特定的IP地址和端口号上。 一旦服务器启动并开始监听客户端连接请求,我们可以使用accept()方法接收客户端的连接请求。当连接完成后,服务器从客户端读取计算请求并执行相应的计算操作,然后将结果发送回客户端。最后,当客户端完成计算操作时,它会关闭连接。 对于客户端,它首先需要解析用户输入的数学表达式,并将它们转换为一个可以通过网络发送的格式,例如字符串。然后,客户端使用socket库中的connect()方法连接到服务器的IP地址和端口号上。 一旦连接已建立,客户端就可以向服务器发送计算请求并等待接收服务器返回的结果。当客户端收到服务器响应后,它将计算结果显示给用户,并关闭连接。 总之,通过socket通信我们可以很容易地实现基于网络的简单计算器。但是注意,在实际的应用中,还需要考虑安全性、性能和数据格式等诸多因素。
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值