Winsock.简单TCP
PS:vs2017 编译C++代码 支持 XP:项目属性-->链接器-->系统-->需要的最小版本--> 输入 "5.1"
1、ZC:测试:c向s 发送长度为0的数据,是可行的。(1)用s和c都在本机 测试,OK (2)用 冬的HP笔记本 和 我的联想小新笔记本 测试,OK
ZC:要想 像UDP那样 像自己发送信息 来退出循环的话... 不太好办... 除非要 使用 非阻塞/异步模型(如 select模型、WSAAsyncSelect模型、WSAEventSelect模型、重叠IO模型),但是 有比较麻烦,还不如直接 使用 Qt的QTcpSocket(Qt的QUdpSocket会丢包,QTcpSocket用了之后 感觉还好)
2、测试代码:
// SampleTCP_01.cpp : This file contains the 'main' function. Program execution begins and ends there. // #include <iostream> #include <stdio.h> int main1(); int main2(); int main(int _argc, char** _argv) { std::cout << "Hello World!\n"; if (_argc <= 1) { printf("Command line no parameter ."); return 0; } printf("%s\n", _argv[0]); if (_argv[1][0] == 's') main1(); else if (_argv[1][0] == 'c') main2(); else printf("Unknown command line parameter : %s\n", _argv[1]); return 0; } #define _WINSOCK_DEPRECATED_NO_WARNINGS #include <iostream> #include <string> #include <winsock2.h> #pragma comment(lib, "ws2_32.lib") #define PORT 58888 #define BUFFER_SIZE 256 static const std::string kExitFlag = "-1"; // 参考:http://c.biancheng.net/cpp/html/3030.html int main1() { WORD winsock_version = MAKEWORD(2, 2); WSADATA wsa_data; if (WSAStartup(winsock_version, &wsa_data) != 0) { std::cout << "Failed to init socket dll!" << std::endl; return 1; } SOCKET server_socket = socket(AF_INET, SOCK_STREAM, IPPROTO_TCP); if (server_socket == INVALID_SOCKET) { std::cout << "Failed to create server socket!" << std::endl; return 2; } sockaddr_in server_addr; server_addr.sin_family = AF_INET; server_addr.sin_port = htons(PORT); server_addr.sin_addr.S_un.S_addr = INADDR_ANY; if (bind(server_socket, (LPSOCKADDR)&server_addr, sizeof(server_addr)) == SOCKET_ERROR) { std::cout << "Failed to bind port!" << std::endl; return 3; } if (listen(server_socket, 10)) { std::cout << "Failed to listen!" << std::endl; return 4; } // 循环接收数据。 sockaddr_in client_addr; int client_addr_len = sizeof(client_addr); std::cout << "Wait for connecting..." << std::endl; // 程序一旦执行到 accept() 就会被阻塞(暂停运行),直到客户端发起请求。 SOCKET client_socket = accept(server_socket, (SOCKADDR*)&client_addr, &client_addr_len); if (client_socket == INVALID_SOCKET) { std::cout << "Failed to accept!" << std::endl; return 5; } std::cout << "Succeed to receive a connection: " << inet_ntoa(client_addr.sin_addr) << std::endl; char recv_buf[BUFFER_SIZE] = {0}; while (true) { // 接收数据。 // 返回值是读取的字节数。没有内容时,等待请求。 int ret = recv(client_socket, recv_buf, BUFFER_SIZE, 0); if (ret < 0) { std::cout << "Failed to receive data!" << std::endl; break; } printf("ret : %d\n", ret); if (ret == 0) { printf("break\n"); break; } std::cout << "Receive from Client: " << recv_buf << std::endl; if (kExitFlag == recv_buf) { std::cout << "Exit!" << std::endl; break; } // 发送数据给客户端。 char* send_data = (char*)"Hello, Tcp Client!\n"; send(client_socket, send_data, strlen(send_data), 0); } // 关闭套接字。 closesocket(client_socket); closesocket(server_socket); // 释放dll。 WSACleanup(); return 0; } #define _WINSOCK_DEPRECATED_NO_WARNINGS #include <iostream> #include <string> #include <winsock2.h> #pragma comment(lib, "ws2_32.lib") #define PORT 58888 //#define SERVER_IP "127.0.0.1" #define SERVER_IP "192.168.2.102" #define BUFFER_SIZE 256 //static const std::string kExitFlag = "-1"; int main2() { // 初始化socket dll。 WORD winsock_version = MAKEWORD(2, 2); WSADATA wsa_data; if (WSAStartup(winsock_version, &wsa_data) != 0) { std::cout << "Failed to init socket dll!" << std::endl; return 1; } SOCKET client_socket = socket(AF_INET, SOCK_STREAM, IPPROTO_TCP); if (client_socket == INVALID_SOCKET) { std::cout << "Failed to create server socket!" << std::endl; return 2; } // 绑定IP和端口。 sockaddr_in server_addr; server_addr.sin_family = AF_INET; server_addr.sin_port = htons(PORT); server_addr.sin_addr.S_un.S_addr = inet_addr(SERVER_IP); // connect() 向服务器发起请求,服务器的IP地址和端口号保存在 sockaddr_in 结构体中。直到服务器传回数据后,connect() 才运行结束。 if (connect(client_socket, (LPSOCKADDR)&server_addr, sizeof(server_addr)) == SOCKET_ERROR) { std::cout << "Failed to connect server!" << std::endl; return 3; } char recv_data[BUFFER_SIZE] = {0}; while (true) { std::string data; std::cout << "Input data: "; std::cin >> data; //if (send(client_socket, data.c_str(), data.size(), 0) < 0) { if (send(client_socket, &recv_data[0], 0, 0) < 0) { std::cout << "Failed to send data!" << std::endl; break; } break; int ret = recv(client_socket, recv_data, BUFFER_SIZE, 0); if (ret < 0) { std::cout << "Failed to receive data!" << std::endl; break; } std::cout << "Receive data from server: " << recv_data << std::endl; if (recv_data == kExitFlag) { std::cout << "Exit!" << std::endl; break; } } closesocket(client_socket); WSACleanup(); return 0; }
3、vs2017 编译C++代码 支持 XP
4、
5、