windows c++ (4) webservice测试服务

1、需求

本文限制比较大,大家可以稍微看下。现场项目是对接webservice,为了方便以后的测试想在本地搭建一个webservice测试服务。

2、实现方法

TCP服务。大家要知道无论是HTTP或者是webservice,底层都是tcp,这个实现方法比较暴力,只适用测试;
工具:Wireshark

3、例子

这里我们用天气预报做个示范。
主要看两个节点:
在这里插入图片描述
上面是发送post请求,下面是回执结果。这里也可以看出测试webservice其实也可以用postman实现,只是其中的一些规范定义需要注意。

发送内容如下:在这里插入图片描述

根据这个发送内容我们其实就可以组postman的发送参数了,大家有需求可以自测下;

接收内容:

Frame 69: 374 bytes on wire (2992 bits), 374 bytes captured (2992 bits) on interface \Device\NPF_{C7F126CF-73B5-4695-8ECD-B75C44B9E500}, id 0
Ethernet II, Src: ASUSTekC_cd:ca:00 (0c:9d:92:cd:ca:00), Dst: IntelCor_c2:08:17 (28:c6:3f:c2:08:17)
Internet Protocol Version 4, Src: 61.147.124.120, Dst:xxxx
Transmission Control Protocol, Src Port: 80, Dst Port: 6547, Seq: 1401, Ack: 1788, Len: 320
[2 Reassembled TCP Segments (1720 bytes): #68(1400), #69(320)]
Hypertext Transfer Protocol
    HTTP/1.1 200 OK\r\n
    Cache-Control: private, max-age=0\r\n
    Content-Type: text/xml; charset=utf-8\r\n
    Content-Encoding: gzip\r\n
    Vary: Accept-Encoding\r\n
    Server: Microsoft-IIS/7.5\r\n
    X-AspNet-Version: 2.0.50727\r\n
    X-Powered-By: ASP.NET\r\n
    Date: Mon, 20 Feb 2023 02:22:17 GMT\r\n
    Content-Length: 1442\r\n
    \r\n
    [HTTP response 1/1]
    [Time since request: 0.008501000 seconds]
    [Request in frame: 66]
    [Request URI: http://www.webxml.com.cn/WebServices/WeatherWS.asmx/getRegionCountry]
    Content-encoded entity body (gzip): 1442 bytes -> 2947 bytes
    File Data: 2947 bytes
eXtensible Markup Language
    <?xml
        version="1.0"
        encoding="utf-8"
        ?>
    <ArrayOfString
        xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
        xmlns:xsd="http://www.w3.org/2001/XMLSchema"
        xmlns="http://WebXml.com.cn/">
        <string>
            阿尔及利亚,3320
            </string>
        <string>
            阿根廷,3522
            </string>
        <string>
            阿曼,3170
            </string>
        <string>
            阿塞拜疆,3176
            </string>
        <string>
            埃及,3317
            </string>
        <string>
            埃塞俄比亚,3314
            </string>
        <string>
            爱尔兰,3246
            </string>
        <string>
            奥地利,3237
            </string>
        <string>
            澳大利亚,368
            </string>
        <string>
            巴基斯坦,3169
            </string>
        <string>
            巴西,3580
            </string>
        <string>
            保加利亚,3232
            </string>
        <string>
            比利时,3243
            </string>
        <string>
            波兰,3235
            </string>
        <string>
            朝鲜,3163
            </string>
        <string>
            丹麦,3245
            </string>
        <string>
            德国,3238
            </string>
        <string>
            俄罗斯,3225
            </string>
        <string>
            法国,3241
            </string>
        <string>
            菲律宾,3151
            </string>
        <string>
            芬兰,3248
            </string>
        <string>
            刚果(金),3377
            </string>
        <string>
            哥伦比亚,3524
            </string>
        <string>
            古巴,344
            </string>
        <string>
            韩国,3162
            </string>
        <string>
            荷兰,3244
            </string>
        <string>
            加拿大,347
            </string>
        <string>
            加纳,3313
            </string>
        <string>
            柬埔寨,3154
            </string>
        <string>
            捷克,3236
            </string>
        <string>
            克罗地亚,3233
            </string>
        <string>
            肯尼亚,3316
            </string>
        <string>
            拉托维亚,3228
            </string>
        <string>
            老挝,3155
            </string>
        <string>
            立陶宛,3227
            </string>
        <string>
            马达加斯加,3312
            </string>
        <string>
            马尔代夫,3166
            </string>
        <string>
            马来西亚,3158
            </string>
        <string>
            马里,3319
            </string>
        <string>
            美国,346
            </string>
        <string>
            蒙古,3165
            </string>
        <string>
            秘鲁,3578
            </string>
        <string>
            缅甸,3160
            </string>
        <string>
            莫桑比克,3311
            </string>
        <string>
            墨西哥,345
            </string>
        <string>
            南非,3310
            </string>
        <string>
            尼泊尔,3164
            </string>
        <string>
            尼日利亚,3379
            </string>
        <string>
            挪威,3250
            </string>
        <string>
            葡萄牙,3239
            </string>
        <string>
            日本,3161
            </string>
        <string>
            瑞典,3249
            </string>
        <string>
            瑞士,3242
            </string>
        <string>
            塞内加尔,3318
            </string>
        <string>
            沙特阿拉伯,3172
            </string>
        <string>
            斯里兰卡,3167
            </string>
        <string>
            泰国,3159
            </string>
        <string>
            坦桑尼亚,3315
            </string>
        <string>
            突尼斯,3321
            </string>
        <string>
            土耳其,3229
            </string>
        <string>
            委内瑞拉,342
            </string>
        <string>
            文莱,3153
            </string>
        <string>
            乌克兰,3226
            </string>
        <string>
            乌兹别克斯坦,3175
            </string>
        <string>
            西班牙,3240
            </string>
        <string>
            希腊,3230
            </string>
        <string>
            新加坡,3157
            </string>
        <string>
            新西兰,369
            </string>
        <string>
            匈牙利,3234
            </string>
        <string>
            叙利亚,3174
            </string>
        <string>
            牙买加,343
            </string>
        <string>
            伊朗,3171
            </string>
        <string>
            意大利,3231
            </string>
        <string>
            印度,3168
            </string>
        <string>
            印度尼西亚,3152
            </string>
        <string>
            英国,3247
            </string>
        <string>
            约旦,3173
            </string>
        <string>
            越南,3156
            </string>
        <string>
            智利,3523
            </string>
        </ArrayOfString>

这里稍微解释下soap协议,SOAP协议可以简单地理解为:

SOAP=RPC+HTTP+XML,即采用HTTP作为通信协议,RPC(Remote Procedure Call Protocol 远程过程调用协议)作为一致性的调用途径,

XML作为数据传送的格式,从而允许服务提供者和服务客户经过防火墙在Internet上进行通信交互。

测试服务实现

//server.cpp
#include<iostream>
#include<winsock.h>   //windows平台的网络库头文件
#pragma comment(lib,"ws2_32.lib")   //库文件
 
#define PORT 5566
#define BUFSIZ 4096
 
int main()
{
    //初始化套接字库
    //WSA  windows socket async  windows异步套接字
    //WSAStartup启动套接字 参数形式:WORD  WSADATA
    //parm1:请求的socket版本 2.2 2.1 1.0
    //parm2:传出参数
    WORD w_req = MAKEWORD(2, 2);//版本号
    WSADATA wsadata;
    //成功:WSAStartup函数返回零
    if (WSAStartup(w_req, &wsadata) != 0) {
        std::cout << "WSAStartup failed" << std::endl;
        return -1;
    } else {
        std::cout << "WSAStartup succeed" << std::endl;
    }
 
    //1.创建空的Socket
    //parm1:af 地址协议族 ipv4 ipv6
    //parm2:type 传输协议类型 流式套接字(SOCK_STREAM) 数据报
    //parm3protocl 使用具体的某个传输协议
    SOCKET s_server = socket(AF_INET, SOCK_STREAM, IPPROTO_TCP);
    if (s_server == INVALID_SOCKET)
    {
        std::cout << "Create socket failed" << std::endl;
        WSACleanup();
        return -1;
    } else {
        std::cout << "Create socket succeed" << std::endl;
    }
    //2.给socket绑定ip地址和端口号
    struct sockaddr_in server_addr;   //sockaddr_in, sockaddr  老版本和新版的区别
    server_addr.sin_family = AF_INET;  //和创建socket时必须一样
    server_addr.sin_port = htons(PORT);  //端口号  大端(高位)存储(本地)和小端(低位)存储(网络),两个存储顺序是反着的  htons 将本地字节序转为网络字节序
    server_addr.sin_addr.s_addr = INADDR_ANY;
    //3.绑定
    if (bind(s_server, (PSOCKADDR)&server_addr, sizeof(sockaddr_in)) == SOCKET_ERROR) {
        std::cout << "Bind failed" << std::endl;
        WSACleanup();
        return -1;
    } else {
        std::cout << "Bind succeed" << std::endl;
    }
 
    //4.设置套接字为监听状态  SOMAXCONN 监听的端口数
    if (listen(s_server, SOMAXCONN) < 0) {
        std::cout << "Listen failed" << std::endl;
        WSACleanup();
        return -1;
    } else {
        std::cout << "Listen succeed" << std::endl;
    }
 
    SOCKET s_client;
    std::cout << "Wait client connect..." << std::endl;
    struct sockaddr_in client_addr;
    int addr_len = sizeof (sockaddr_in);
    s_client = accept(s_server, (SOCKADDR*)&client_addr, &addr_len);
    if (s_client == INVALID_SOCKET) {
        std::cout << "Accept failed" << std::endl;
        WSACleanup();
        return -1;
    }
 
    char buf[BUFSIZ];
    ZeroMemory(buf, BUFSIZ);
    while (true) {
        int ret = recv(s_client, buf, BUFSIZ, 0);
        if (ret > 0){
        	//这里没做解析有需求可以在这里解析
            std::cout << "Recv from client: " << buf << std::endl;
        } else if (ret == 0) {
            std::cout << "s_client closed" << std::endl;
            closesocket(s_server);
            WSACleanup();
            return -1;
        } else {
            std::cout << "Recv failed: " << GetLastError() << std::endl;
            closesocket(s_server);
            closesocket(s_client);
            WSACleanup();
            return -1;
        }
 		
 		//直接组的固定数据,有需求可以变动 
 		//tcp实现webservice主要就是回复的数据,满足他需要的soap协议就行
 		string strSendDat="";
		strSendDat =  "HTTP/1.0 200 OK\r\n";
		strSendDat +=  "Cache-Control: private, max-age=0\r\n";
		strSendDat +=  "Content-Type: text/xml; charset=utf-8\r\n";
		strSendDat +=  "Content-Encoding: gzip\r\n";
		strSendDat +=  "Vary: Accept-Encoding\r\n";
		strSendDat +=  "Server: Microsoft-IIS/7.5\r\n";
		strSendDat +=  "X-AspNet-Version: 2.0.50727\r\n";
		strSendDat +=  "X-Powered-By: ASP.NET\r\n";
		strSendDat +=  "Date: Mon, 20 Feb 2023 02:22:17 GMT\r\n";
		strSendDat +=  "Content-Length:";

		//回复xml信息
		string strXML = "<?xml version=\"1.0\" encoding=\"utf-8\" ?>";
		strXML += "<ArrayOfString xmlns:xsi=\"http://www.w3.org/2001/XMLSchema-instance\" \
        xmlns:xsd=\"http://www.w3.org/2001/XMLSchema\" \
        xmlns=\"http://WebXml.com.cn/\">";
        strXML += "<string>\
            阿尔及利亚,3320\
            </string>\
        <string>\
            阿根廷,3522\
            </string>"
         //   ...... 太多不写齐了
         strXML += "</ArrayOfString>";
		
		long ldalen = strlen(strXML.c_str());
		char szTem[32];
		sprintf(szTem,"%d \r\n\r\n",ldalen);
		strSendDat += szTem;	
		strSendDat += xmldata;
		
        ret = send(s_client, strSendDat.c_str(), strlen(strSendDat.c_str()), 0);
        if (SOCKET_ERROR != ret) {
            std::cout << "Send to client: " << buf << std::endl;
        } else {
            std::cout << "Send failed: " << GetLastError() << std::endl;
            closesocket(s_server);
            closesocket(s_client);
            WSACleanup();
            return -1;
        }
    }
 
    //关闭套接字
    closesocket(s_server);
    closesocket(s_client);
    //释放DLL资源
    WSACleanup();
    return 0;
}
 

这只是一个简单的测试,如果需要实现服务可以创建线程将接收拎出来。

  • 0
    点赞
  • 1
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值