Windows和Linux_c++写法_简易计算器_TCP
c++写法_TCP下Windows和Linux的简易计算器
·
关键要点
如何在char数组中存储一个很大的数值
- 第一位一定要是存储的数值
- 示例以4字节作为一个数据的存储空间
#include<iostream>
using namespace std;
int main(int argc,char **argv)
{
char p[8];
//用4字节存储一个操作数
//数组存数据时先取地址再转换类型
int *a=(int*)&p[0];
*a=1000;
int *b=(int *)&p[4];
*b=11111;
//取数据时先转换char数组变为int数组,再解析数据
int *p_int=(int*) p;
for(int i=0;i<2;i++)
{
cout<<p_int[i]<<endl;
}
system("pause");
return 0;
}
int类型转char *类型
该事项用于Windows服务端
的send(clntSock,(char*)&result,sizeof(result),0);
,其中result
类型原本为int,但由于send
需要传输char *类型而进行的强制转换。
int b=1000;
char *a=(char*)&b;
Windows TCP简易计算器
服务端
#include <iostream>
#include <WinSock2.h>
#include <string.h>
using namespace std;
int calculate(int count,int *operand,char *ope)
{
int res=operand[0];
switch (ope[0])
{
case '+':
for(int i=1;i<count;i++)
res+=operand[i];
break;
case '-':
for(int i=1;i<count;i++)
res-=operand[i];
break;
case '*':
for(int i=1;i<count;i++)
res*=operand[i];
break;
case '/':
for(int i=1;i<count;i++)
res/=operand[i];
break;
}
return res;
}
int main(int argc, char **argv)
{
WSADATA wsa;
WSAStartup(MAKEWORD(2, 2), &wsa);
SOCKET sock = socket(AF_INET, SOCK_STREAM, IPPROTO_TCP);
sockaddr_in sock_addr;
memset(&sock_addr, 0, sizeof(sock_addr));
sock_addr.sin_family = AF_INET;
sock_addr.sin_addr.s_addr = htonl(INADDR_ANY);
sock_addr.sin_port = htons(atoi(argv[1]));
bind(sock, (sockaddr *)&sock_addr, sizeof(sock_addr));
listen(sock, 5);
SOCKADDR clntAddr;
int nSize = sizeof(SOCKADDR);
for (int i = 0; i < 5; i++)
{
SOCKET clntSock = accept(sock, (SOCKADDR *)&clntAddr,&nSize);
// char count[4];
char count[1];
recv(clntSock,count,1,0);
int operand_count=count[0];
char operand[50];
for(int i=0;i<operand_count;i++)
{
recv(clntSock,&operand[i*4],4,0);
// cout<<operand[i]<<endl;
}
char ope[1];
recv(clntSock,ope,1,0);
int result=calculate(operand_count,(int*)operand,ope);
char sendMsg[4];
//int类型强制转换char*类型
send(clntSock,(char*)&result,sizeof(result),0);
closesocket(clntSock);
}
closesocket(sock);
WSACleanup();
return 0;
}
客户端
#include<iostream>
#include<WinSock2.h>
#include<string.h>
#define BUFSIZE 50
#define OPSZ 4
using namespace std;
int main(int argc,char **argv)
{
WSADATA wsa;
WSAStartup(MAKEWORD(2,2),&wsa);
char msg[BUFSIZE];
SOCKET sock=socket(AF_INET,SOCK_STREAM,0);
SOCKADDR_IN sock_addr;
memset(&sock_addr,0,sizeof(sock_addr));
sock_addr.sin_family=AF_INET;
sock_addr.sin_addr.s_addr=inet_addr(argv[1]);
sock_addr.sin_port=htons(atoi(argv[2]));
connect(sock,(sockaddr*)&sock_addr,sizeof(sock_addr));
cout<<"connected..."<<endl;
int operand_count;
cout<<"Operand count: ";
cin>>operand_count;
msg[0]=(char)operand_count;//注意范围为0=127
for(int i=0;i<operand_count;i++)
{
cout<<"Operand "<<i+1<<": ";
//将msg4个位作为一个数字的存储空间传输数值地址
int *p=(int*)&msg[i*OPSZ+1];
cin>>*p;
}
cout<<"Operator: ";
cin>>msg[operand_count*OPSZ+1];
send(sock,msg,operand_count*OPSZ+2,0);
char res[4];
recv(sock,res,OPSZ,0);
int *res_num=(int*)res;//res得到的是数值的地址,需要先转换为(int*)类型,注意该类型为int数组指针
cout<<"Operation result: "<<*res_num<<endl;
closesocket(sock);
WSACleanup();
system("pause");
return 0;
}
LINUX TCP简易计算器
服务端
#include <stdio.h>
#include <stdlib.h>
#include <string.h>
#include <unistd.h>
#include <arpa/inet.h>
#include <sys/socket.h>
#define BUF_SIZE 50
#define OPSZ 4
void error_handling(char *message);
int calculate(int operand_count, int operands[], char ope);
int main(int argc, char *argv[])
{
int serv_sock, clnt_sock;
struct sockaddr_in serv_addr, clnt_addr;
char message[BUF_SIZE];
if (argc != 2)
{
printf("Usage : %s <port>", argv[0]);
exit(1);
}
serv_sock = socket(PF_INET, SOCK_STREAM, 0);
memset(&serv_addr, 0, sizeof(serv_addr));
serv_addr.sin_family = AF_INET;
serv_addr.sin_addr.s_addr = htonl(INADDR_ANY);
serv_addr.sin_port = htons(atoi(argv[1]));
if (bind(serv_sock, (struct sockaddr *)&serv_addr, sizeof(serv_addr)) == -1)
error_handling("bind() error");
if (listen(serv_sock, 5) == -1)
error_handling("listen() error");
socklen_t clnt_addr_sz = sizeof(clnt_addr);
for (int i = 0; i < 5; i++)
{
if ((clnt_sock = accept(serv_sock, (struct sockaddr *)&clnt_addr, &clnt_addr_sz)) == -1)
error_handling("accept() error");
int operand_count;
read(clnt_sock, &operand_count, 1); // 首先读取第 1 个字节,获取操作数的数量
char operands[BUF_SIZE];
for (int i = 0; i < operand_count; i++)
{
read(clnt_sock, &operands[i * OPSZ], OPSZ); // 根据操作数数量,依次读取操作数
}
char ope;
read(clnt_sock, &ope, 1); // 读取运算符
int result = calculate(operand_count, (int *)operands, ope);
write(clnt_sock, (char *)&result, sizeof(result)); // 发送计算结果
close(clnt_sock);
}
close(serv_sock);
return 0;
}
int calculate(int operand_count, int operands[], char ope)
{
int result = operands[0];
switch (ope)
{
case '+':
for (int i = 1; i < operand_count; i++)
result += operands[i];
break;
case '-':
for (int i = 1; i < operand_count; i++)
result -= operands[i];
break;
case '*':
for (int i = 1; i < operand_count; i++)
result *= operands[i];
break;
}
return result;
}
void error_handling(char *message)
{
fputs(message, stderr);
fputc('\n', stderr);
exit(1);
}
客户端
#include <stdio.h>
#include <stdlib.h>
#include <string.h>
#include <unistd.h>
#include <arpa/inet.h>
#include <sys/socket.h>
#include<iostream>
using namespace std;
#define BUF_SIZE 50
#define OPSZ 4 // 定义每个操作数在 TCP 报文中占用的字节数
void error_handling(char *message);
int main(int argc, char *argv[])
{
int sock;
char opmsg[BUF_SIZE]; // opmsg 用来存储要发送的数据,注意是 char 类型数组
struct sockaddr_in serv_addr;
int operand_count, result;
if (argc != 3)
{
printf("Usage : %s <IP> <port>\n", argv[0]);
exit(1);
}
sock = socket(PF_INET, SOCK_STREAM, 0);
if (sock == -1)
error_handling("socket() error");
memset(&serv_addr, 0, sizeof(serv_addr));
serv_addr.sin_family = AF_INET;
serv_addr.sin_addr.s_addr = inet_addr(argv[1]);
serv_addr.sin_port = htons(atoi(argv[2]));
if (connect(sock, (struct sockaddr *)&serv_addr, sizeof(serv_addr)))
error_handling("connect() error");
else
puts("Connecting..........\n");
fputs("Operand count: ", stdout);
// scanf("%d", &operand_count);
cin>>operand_count;
opmsg[0] = (char)operand_count; // 数据的第一个字节存储操作数的数量,注意要将变量类型转换为 char。
for (int i = 0; i < operand_count; i++)
{
printf("Operand %d: ", i + 1);
// scanf("%d", (int *)&opmsg[i * OPSZ + 1]);
// 从第二个字节开始每四个字节存储一个操作数,向数组存数据时先取地址再转换类型。
//相当于在opmsg上放入p指针的地址
int *p=(int*)&opmsg[i*OPSZ+1];
cin>>*p;
}
fgetc(stdin);
fputs("Operator: ", stdout);
// scanf("%c", &opmsg[operand_count * OPSZ + 1]); // 再用一个字节存储运算符
cin>>opmsg[operand_count*OPSZ+1];
// cout<<"before write"<<endl;
write(sock, opmsg, operand_count * OPSZ + 2); // 发送数据
read(sock, &result, OPSZ); // 接收运算结果:运算结果是一个 4 字节的操作数
printf("Operation result: %d\n", result);
close(sock);
return 0;
}
void error_handling(char *message)
{
fputs(message, stderr);
fputc('\n', stderr);
exit(1);
}
更多推荐
已为社区贡献1条内容
所有评论(0)