基于tcp协议的计算器程序

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

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

服务器:

 

#include "stdafx.h"
#include
#include
#include
#include

#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
#include
#include
#include

#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;
}

 

 

 

 

 

你可能感兴趣的:(vc++/c++/mfc学习)