本文限制比较大,大家可以稍微看下。现场项目是对接webservice,为了方便以后的测试想在本地搭建一个webservice测试服务。
TCP服务。大家要知道无论是HTTP或者是webservice,底层都是tcp,这个实现方法比较暴力,只适用测试;
工具:Wireshark
这里我们用天气预报做个示范。
主要看两个节点:
上面是发送post请求,下面是回执结果。这里也可以看出测试webservice其实也可以用postman实现,只是其中的一些规范定义需要注意。
根据这个发送内容我们其实就可以组postman的发送参数了,大家有需求可以自测下;
Frame 69: 374 bytes on wire (2992 bits), 374 bytes captured (2992 bits) on interface DeviceNPF_{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 ProtocolHTTP/1.1 200 OKrnCache-Control: private, max-age=0rnContent-Type: text/xml; charset=utf-8rnContent-Encoding: gziprnVary: Accept-EncodingrnServer: Microsoft-IIS/7.5rnX-AspNet-Version: 2.0.50727rnX-Powered-By: ASP.NETrnDate: Mon, 20 Feb 2023 02:22:17 GMTrnContent-Length: 1442rnrn[HTTP response 1/1][Time since request: 0.008501000 seconds][Request in frame: 66][Request URI: .asmx/getRegionCountry]Content-encoded entity body (gzip): 1442 bytes -> 2947 bytesFile Data: 2947 bytes
eXtensible Markup Language<?xmlversion="1.0"encoding="utf-8"?><ArrayOfStringxmlns:xsi=""xmlns:xsd=""xmlns="/"><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 4096int 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 " << 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 OKrn";strSendDat += "Cache-Control: private, max-age=0rn";strSendDat += "Content-Type: text/xml; charset=utf-8rn";strSendDat += "Content-Encoding: gziprn";strSendDat += "Vary: Accept-Encodingrn";strSendDat += "Server: Microsoft-IIS/7.5rn";strSendDat += "X-AspNet-Version: 2.0.50727rn";strSendDat += "X-Powered-By: ASP.NETrn";strSendDat += "Date: Mon, 20 Feb 2023 02:22:17 GMTrn";strSendDat += "Content-Length:";//回复xml信息string strXML = "<?xml version="1.0" encoding="utf-8" ?>";strXML += "<ArrayOfString xmlns:xsi="" xmlns:xsd="" xmlns="/">";strXML += "<string>阿尔及利亚,3320</string><string>阿根廷,3522</string>"// ...... 太多不写齐了strXML += "</ArrayOfString>";long ldalen = strlen(strXML.c_str());char szTem[32];sprintf(szTem,"%d rnrn",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;
}
这只是一个简单的测试,如果需要实现服务可以创建线程将接收拎出来。
本文发布于:2024-01-29 12:32:36,感谢您对本站的认可!
本文链接:https://www.4u4v.net/it/170650276115312.html
版权声明:本站内容均来自互联网,仅供演示用,请勿用于商业和其他非法用途。如果侵犯了您的权益请与我们联系,我们将在24小时内删除。
留言与评论(共有 0 条评论) |