赞
踩
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>
1.创建套接字
2.填充服务器的网络信息结构体
3.将套接字和服务器的网络信息结构体绑定
4.把套接字设置成被动监听状态
5.阻塞等待客户端连接
6.收发数据
7.关闭套接字
1.创建套接字
2.填充服务器的网络信息结构体
3.与服务器建立连接
4.收发数据
5.关闭套接字
#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);//error int 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; }
#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端:
Copyright © 2003-2013 www.wpsshop.cn 版权所有,并保留所有权利。