客户端发送操作数个数,操作数,运算符到客户端,客户端计算后返回。同一时刻只服务一个客户端。
在字符数组中,操作数个数占第一个字节,紧接着每一个操作数占四个字节,最后运算符占一个字节。因为是不同类型,因此数组为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;
}