博客
关于我
windows网络编程 | 基于控制台的简单服务器/客户端程序(5.4小节随书案例)
阅读量:286 次
发布时间:2019-03-01

本文共 6780 字,大约阅读时间需要 22 分钟。

基于流式套接字的回射程序开发

5.4 编程举例

本节通过一个Windows控制台应用程序实现基于流式套接字的回射功能。回射是指服务器接收客户发来的字符,并将接收到的内容再次发送回客户端,以检测网络和主机运行状态。本节设计客户和服务器两个独立的网络应用程序,结合网络操作的基本步骤讲述流式套接字编程中各函数的使用方法。

5.4.1 基于流式套接字的回射客户端编程操作

客户端程序接收命令行参数argv[1]传入的服务器端地址,与服务器进行连接。Visual Studio编译器设置命令行参数方法:项目(右键)属性——》调试——》命令参数。

客户端完整代码:

#define WIN32_LEAN_AND_MEAN#include 
#include
#include
#include
#include
#pragma comment (lib, "Ws2_32.lib")#pragma comment (lib, "Mswsock.lib")#pragma comment (lib, "AdvApi32.lib")#define DEFAULT_BUFLEN 512#define DEFAULT_PORT "27015"int __cdecl main(int argc, char **argv) { WSADATA wsaData; SOCKET ConnectSocket = INVALID_SOCKET; struct addrinfo *result = NULL, *ptr = NULL, hints; char sendbuf[] = "this is a test"; char recvbuf[DEFAULT_BUFLEN]; int iResult; int recvbuflen = DEFAULT_BUFLEN; if (argc != 2) { printf("usage: %s server-name\n", argv[0]); return 1; } iResult = WSAStartup(MAKEWORD(2, 2), &wsaData); if (iResult != 0) { printf("WSAStartup failed with error: %d\n", iResult); return 1; } ZeroMemory(&hints, sizeof(hints)); hints.ai_family = AF_UNSPEC; hints.ai_socktype = SOCK_STREAM; hints.ai_protocol = IPPROTO_TCP; iResult = getaddrinfo(argv[1], DEFAULT_PORT, &hints, &result); if (iResult != 0) { printf("getaddrinfo failed with error: %d\n", iResult); WSACleanup(); return 1; } for (ptr = result; ptr != NULL; ptr = ptr->ai_next) { ConnectSocket = socket(ptr->ai_family, ptr->ai_socktype, ptr->ai_protocol); if (ConnectSocket == INVALID_SOCKET) { printf("socket failed with error: %ld\n", WSAGetLastError()); WSACleanup(); return 1; } iResult = connect(ConnectSocket, ptr->ai_addr, (int)ptr->ai_addrlen); if (iResult == SOCKET_ERROR) { closesocket(ConnectSocket); ConnectSocket = INVALID_SOCKET; continue; } break; } freeaddrinfo(result); if (ConnectSocket == INVALID_SOCKET) { printf("Unable to connect to server!\n"); WSACleanup(); return 1; } iResult = send(ConnectSocket, sendbuf, (int)strlen(sendbuf), 0); if (iResult == SOCKET_ERROR) { printf("send failed with error: %d\n", WSAGetLastError()); closesocket(ConnectSocket); WSACleanup(); return 1; } printf("Bytes Sent: %ld\n", iResult); iResult = shutdown(ConnectSocket, SD_SEND); if (iResult == SOCKET_ERROR) { printf("shutdown failed with error: %d\n", WSAGetLastError()); closesocket(ConnectSocket); WSACleanup(); return 1; } do { iResult = recv(ConnectSocket, recvbuf, recvbuflen, 0); if (iResult > 0) { printf("Bytes received: %d\n", iResult); } else if (iResult == 0) { printf("Connection closed\n"); } else { printf("recv failed with error: %d\n", WSAGetLastError()); closesocket(ConnectSocket); WSACleanup(); return 1; } } while (iResult > 0); closesocket(ConnectSocket); WSACleanup(); return 0;}

5.4.2 基于流式套接字的回射服务器端编程操作

服务器端完整代码:

#undef UNICODE#define WIN32_LEAN_AND_MEAN#include 
#include
#include
#include
#include
#pragma comment (lib, "Ws2_32.lib")#define DEFAULT_BUFLEN 512#define DEFAULT_PORT "27015"int __cdecl main(void) { WSADATA wsaData; int iResult; SOCKET ListenSocket = INVALID_SOCKET; SOCKET ClientSocket = INVALID_SOCKET; struct addrinfo *result = NULL; struct addrinfo hints; int iSendResult; char recvbuf[DEFAULT_BUFLEN]; int recvbuflen = DEFAULT_BUFLEN; iResult = WSAStartup(MAKEWORD(2, 2), &wsaData); if (iResult != 0) { printf("WSAStartup failed with error: %d\n", iResult); return 1; } ZeroMemory(&hints, sizeof(hints)); hints.aifamily = AF_INET; hints.aisocktype = SOCK_STREAM; hints.aiprotocol = IPPROTO_TCP; hints.aiflags = AI_PASSIVE; iResult = getaddrinfo(NULL, DEFAULT_PORT, &hints, &result); if (iResult != 0) { printf("getaddrinfo failed with error: %d\n", iResult); WSACleanup(); return 1; } ListenSocket = socket(result->ai_family, result->ai_socktype, result->ai_protocol); if (ListenSocket == INVALID_SOCKET) { printf("socket failed with error: %ld\n", WSAGetLastError()); freeaddrinfo(result); WSACleanup(); return 1; } iResult = bind(ListenSocket, result->ai_addr, (int)result->ai_addrlen); if (iResult == SOCKET_ERROR) { printf("bind failed with error: %d\n", WSAGetLastError()); freeaddrinfo(result); closesocket(ListenSocket); WSACleanup(); return 1; } freeaddrinfo(result); iResult = listen(ListenSocket, SOMAXCONN); if (iResult == SOCKET_ERROR) { printf("listen failed with error: %d\n", WSAGetLastError()); closesocket(ListenSocket); WSACleanup(); return 1; } ClientSocket = accept(ListenSocket, NULL, NULL); if (ClientSocket == INVALID_SOCKET) { printf("accept failed with error: %d\n", WSAGetLastError()); closesocket(ListenSocket); WSACleanup(); return 1; } closesocket(ListenSocket); do { iResult = recv(ClientSocket, recvbuf, recvbuflen, 0); if (iResult > 0) { printf("Bytes received: %d\n", iResult); iSendResult = send(ClientSocket, recvbuf, iResult, 0); if (iSendResult == SOCKET_ERROR) { printf("send failed with error: %d\n", WSAGetLastError()); closesocket(ClientSocket); WSACleanup(); return 1; } printf("Bytes sent: %d\n", iSendResult); } else if (iResult == 0) { printf("Connection closing...\n"); } else { printf("recv failed with error: %d\n", WSAGetLastError()); closesocket(ClientSocket); WSACleanup(); return 1; } } while (iResult > 0); iResult = shutdown(ClientSocket, SD_SEND); if (iResult == SOCKET_ERROR) { printf("shutdown failed with error: %d\n", WSAGetLastError()); closesocket(ClientSocket); WSACleanup(); return 1; } closesocket(ClientSocket); WSACleanup(); return 0;}

运行实例

运行环境:Visual Studio 2019,Windows 10专业版。

1. 创建解决方案

新建工程,并创建两个项目,分别用于编写服务器端和客户端的程序。将上述代码写入各自的.cpp文件中。

2. 客户端设置

设置客户端命令行参数:鼠标右键cli项目——》属性,选择调试,在命令参数中输入服务器IP地址。由于是本地测试,这里使用本地环回地址127.0.0.1

3. 多项目启动设置

由于需要同时运行服务器和客户端两个程序,这里设置编译器为多项目启动方式。

3.1 设置多项目启动

右键解决方案——》属性,选择通用属性——》启动项目——》多个启动项目,将sercli都设置为启动。

3.2 设置启动顺序

在项目依赖项中选择cli项目依赖于ser

4. 启动运行

点击运行,运行结果如图所示。

转载地址:http://deio.baihongyu.com/

你可能感兴趣的文章
nodejs 发起 GET 请求示例和 POST 请求示例
查看>>
NodeJS 导入导出模块的方法( 代码演示 )
查看>>
nodejs 开发websocket 笔记
查看>>
nodejs 的 Buffer 详解
查看>>
NodeJS 的环境变量: 开发环境vs生产环境
查看>>
nodejs 读取xlsx文件内容
查看>>
nodejs 运行CMD命令
查看>>
Nodejs+Express+Mysql实现简单用户管理增删改查
查看>>
nodejs+nginx获取真实ip
查看>>
nodejs-mime类型
查看>>
NodeJs——(11)控制权转移next
查看>>
NodeJS、NPM安装配置步骤(windows版本)
查看>>
NodeJS、NPM安装配置步骤(windows版本)
查看>>
nodejs下的express安装
查看>>
nodejs与javascript中的aes加密
查看>>
nodejs中Express 路由统一设置缓存的小技巧
查看>>
nodejs中express的使用
查看>>
Nodejs中搭建一个静态Web服务器,通过读取文件获取响应类型
查看>>
Nodejs中的fs模块的使用
查看>>
NodeJS使用淘宝npm镜像站的各种姿势
查看>>