第一句子网 - 唯美句子、句子迷、好句子大全
第一句子网 > TCP网络编程----C/S模型 (客户端/服务器模型)的代码实现

TCP网络编程----C/S模型 (客户端/服务器模型)的代码实现

时间:2022-05-14 21:06:48

相关推荐

TCP网络编程----C/S模型 (客户端/服务器模型)的代码实现

TCP网络编程----C/S模型 (客户端/服务器模型)的代码实现

client发送数据到server,server对数据进行提取并根据用户输入的操作符进行两个数的计算,并将计算结果传给client。(实际上,这个例子已经有了云计算的雏形)

前言

本文章使用的是Ubuntu操作系统和C语言实现了简单的客户端(client)和服务器端(server)的通信。

本文代码实现所需要用到的头文件如下:

#include <arpa/inet.h>#include <netinet/in.h>#include <stdio.h>#include <stdlib.h>#include <string.h>#include <sys/socket.h>#include <sys/types.h>#include <unistd.h>

一、TCP网络编程流程

服务器流程:

1.创建套接字

2.填充服务器的网络信息结构体

3.将套接字和服务器的网络信息结构体绑定

4.把套接字设置成被动监听状态

5.阻塞等待客户端连接

6.收发数据

7.关闭套接字

客户端流程:

1.创建套接字

2.填充服务器的网络信息结构体

3.与服务器建立连接

4.收发数据

5.关闭套接字

二、代码实现

1.服务器代码实现

#include <net_head.h>/*功能:根据客户端传入的数据进行计算(两个数的计算)参数:@buf:从客户端接收的数据,存放的buf数组的首地址@len:数组的长度返回值:成功返回计算的结果*/int calculate(char* buf, int len){int lvalue = 0;int rvalue = 0;char operator;int i = 0;int ret = 0;//(1) 循环找到第一个数字的位置while ((buf[i] < '0' || buf[i] > '9') && i < len)i++;//(2) 从第一个数字的位置往后找一串数字,作为左操作数for (; buf[i] >= '0' && buf[i] <= '9' && i < len; i++) {lvalue *= 10;lvalue += buf[i] - '0';}//(3) 循环找运算符for (; buf[i] != '+' && buf[i] != '-' && buf[i] != '*' && buf[i] != '/' && buf[i] != '%' && i < len; i++) {printf("%c", buf[i]);}operator= buf[i];//(4) 循环找右操作数开头的第一个数字while ((buf[i] < '0' || buf[i] > '9') && i < len)i++;//(5) 从第一个数字的位置往后找一串数字,作为右操作数for (; buf[i] >= '0' && buf[i] <= '9' && i < len; i++) {rvalue *= 10;rvalue += buf[i] - '0';}printf("%d %c %d\n", lvalue, operator, rvalue);//(6) 根据操作符做运算switch (operator) {case '+':ret = lvalue + rvalue;break;case '-':ret = lvalue - rvalue;break;case '*':ret = lvalue * rvalue;break;case '/':ret = lvalue / rvalue;break;case '%':ret = lvalue % rvalue;break;default:printf("Input error\n");break;}return ret;}int main(int argc, const char* argv[]){// 1.创建套接字int sockfd = socket(AF_INET, SOCK_STREAM, 0);if (sockfd == -1) {perror("socket error");exit(-1);}// 2.填充服务器的网络信息结构体struct sockaddr_in serverAddr;serverAddr.sin_family = AF_INET;serverAddr.sin_addr.s_addr = inet_addr("这里填server端虚拟机的ip地址");serverAddr.sin_port = htons(这里填任意一个合适的端口号);// 3.将套接字和服务器的网络信息结构体绑定socklen_t serverAddr_len = sizeof(serverAddr);if (-1 == bind(sockfd, (struct sockaddr*)&serverAddr, serverAddr_len)) {perror("bind error");exit(-1);}// 4.把套接字设置成被动监听状态if (-1 == listen(sockfd, 5)) {perror("listen error");exit(-1);}// 5.阻塞等待客户端连接// int acceptfd = accept(sockfd, (struct sockaddr*)&serverAddr, &serverAddr_len);//errorint acceptfd = accept(sockfd, NULL, NULL);if (acceptfd == -1) {perror("accept error");exit(-1);}// 6.接收数据,并作两个数的计算char buf[128] = "";int len = sizeof(buf);read(acceptfd, buf, sizeof(buf));int ret = calculate(buf, len);// 7.发送数据write(acceptfd, &ret, sizeof(ret));// 8.关闭套接字close(acceptfd);close(sockfd);return 0;}

2.客户端代码的实现

#include <net_head.h>int main(int argc, const char* argv[]){// 1.创建套接字int sockfd = socket(AF_INET, SOCK_STREAM, 0);if (sockfd == -1) {perror("socket error");exit(-1);}// 2.填充服务器的网络信息结构体struct sockaddr_in serverAddr;serverAddr.sin_family = AF_INET;serverAddr.sin_addr.s_addr = inet_addr("这里填server端主机的IP地址");serverAddr.sin_port = htons(这里填任意一个合适的端口号,eg:7777,server端配置端口转发的时候,也要填这个端口号);// 3.与服务器简历连接if (-1 == connect(sockfd, (const struct sockaddr*)&serverAddr, sizeof(serverAddr))) {perror("connect error");exit(-1);}printf("Connected to server..\n");// 4.发送数据char buf[128] = "";printf("Please input : ");fgets(buf, sizeof(buf), stdin);buf[strlen(buf) - 1] = '\0';write(sockfd, buf, sizeof(buf));// 5.接收数据int ret = 0;read(sockfd, &ret, sizeof(ret));printf("From server : result is >> %d\n", ret);// 6.关闭套接字close(sockfd);return 0;}

三、两台不同虚拟机之间的通信

注意事项:

本文使用的是VMware软件,对于端口转发的配置,有以下3点注意事项:1.服务器端要关闭防火墙!2.client代码中的ip地址要写server端的主机ip(注意不是虚拟机ip)3.server端所在的主机要配置端口转发:端口号和client代码中的端口号要保持一致):

结果展示

server端

client端:

本内容不代表本网观点和政治立场,如有侵犯你的权益请联系我们处理。
网友评论
网友评论仅供其表达个人看法,并不表明网站立场。