C++ Winsock
由于兼容的问题更新下winsock,有较好的移植性:客户端是非阻塞的,服务器是阻塞的!
Win32控制台:
数据收发:
服务器向客户端发送一个txt文本内容和一个结构体数据;
服务器代码:
#include "stdafx.h" #undef UNICODE #define WIN32_LEAN_AND_MEAN #include <windows.h> #include <winsock2.h> #include <ws2tcpip.h> #include <stdlib.h> #include <stdio.h> #include<fstream> #include<iostream> #include<string> using namespace std; // Need to link with Ws2_32.lib #pragma comment (lib, "Ws2_32.lib") // #pragma comment (lib, "Mswsock.lib") #define DEFAULT_BUFLEN 512 #define DEFAULT_PORT "27015" int main()//__cdecl { 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; // Initialize Winsock 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_INET; hints.ai_socktype = SOCK_STREAM; hints.ai_protocol = IPPROTO_TCP; hints.ai_flags = AI_PASSIVE; // Resolve the server address and port iResult = getaddrinfo(NULL, DEFAULT_PORT, &hints, &result); if (iResult != 0) { printf("getaddrinfo failed with error: %d\n", iResult); WSACleanup(); return 1; } // Create a SOCKET for connecting to server 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; } // Setup the TCP listening socket 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; } // Accept a client socket ClientSocket = accept(ListenSocket, NULL, NULL); if (ClientSocket == INVALID_SOCKET) { printf("accept failed with error: %d\n", WSAGetLastError()); closesocket(ListenSocket); WSACleanup(); return 1; } printf("accept success :\n"); // No longer need server socket closesocket(ListenSocket); string shader_modifiy; std::fstream file_read; file_read.open("shader_test.txt", std::ios::in); std::string transmit; while (getline(file_read, transmit)) { shader_modifiy += transmit; } shader_modifiy += '\0'; file_read.close(); char *p = new char[shader_modifiy.length()]; for (int i = 0; i < shader_modifiy.length(); i++) { p[i] = shader_modifiy[i]; } string shader_modifiy1 = p; delete[]p; shader_modifiy1 += "~"; while (true) { cout << "输入(start)开始更改,输入(end)结束服务:" << endl; cout << "输入发送内容:"; while (cin.getline(recvbuf, 500)) { string rcover = recvbuf; if (rcover == "end")break; if (rcover == "start") { cout << "请以m1~m2~m3~m_roll~m_pitch~m_rotate格式输入要修改的数据(m1为m1*R,m2为m2*G,m3为m3*B):" << endl; char transmit1[100]; cin.getline(transmit1, 100); string transmit_str = transmit1; transmit_str += '\0'; string transmit_string = shader_modifiy1 + transmit_str; char *p1 = new char[transmit_string.length()]; for (int i = 0; i < transmit_string.length(); i++) { p1[i] = transmit_string[i]; } send(ClientSocket, p1, strlen(p1) + 1, 0); //字符串还有个结束标志, delete[] p1; //send(sclient,client_send.m1,) } } } return 0; }
客户端代码:
#include "stdafx.h" #define WIN32_LEAN_AND_MEAN #include <windows.h> #include <winsock2.h> #include <ws2tcpip.h> #include <stdlib.h> #include <stdio.h> #include <iostream> #include <string> #include<cstring> #include<vector> #include<sstream> // Need to link with Ws2_32.lib, Mswsock.lib, and Advapi32.lib #pragma comment (lib, "Ws2_32.lib") #pragma comment (lib, "Mswsock.lib") #pragma comment (lib, "AdvApi32.lib") #define DEFAULT_BUFLEN 512 #define DEFAULT_PORT "27015" using namespace std; typedef struct Date { float m1; float m2; float m3; float m_roll; float m_pitch; float m_rotate; }Datablock; string test; void splitEx(vector<string>&strs, const string& src, string separate_character) { int separate_characterLen = separate_character.size();//分割字符串的长度,这样就可以支持如“,,”多字符串的分隔符 int lastPosition = 0, index = -1; while (-1 != (index = src.find(separate_character, lastPosition))) { strs.push_back(src.substr(lastPosition, index - lastPosition)); lastPosition = index + separate_characterLen; } string lastString = src.substr(lastPosition);//截取最后一个分隔符后的内容 if (!lastString.empty()) strs.push_back(lastString);//如果最后一个分隔符后还有内容就入队 } float str_float(string a) { float b; stringstream ss; //string 转 int ss << a; ss >> b; return b; } int main() { WSADATA wsaData; SOCKET ConnectSocket = INVALID_SOCKET; struct addrinfo *result = NULL, *ptr = NULL, hints; char recvbuf[DEFAULT_BUFLEN]; int iResult; int recvbuflen = DEFAULT_BUFLEN; // Initialize Winsock 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; string ip; cout << "please enter server ip:" << endl; cin >> ip; cout << "server ip is:" << ip << endl; // Resolve the server address and port iResult = getaddrinfo(ip.c_str(), DEFAULT_PORT, &hints, &result); if (iResult != 0) { printf("getaddrinfo failed with error: %d\n", iResult); WSACleanup(); return 1; } // Attempt to connect to an address until one succeeds for (ptr = result; ptr != NULL; ptr = ptr->ai_next) { // Create a SOCKET for connecting to server 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; } // Connect to server. iResult = connect(ConnectSocket, ptr->ai_addr, (int)ptr->ai_addrlen); if (iResult == SOCKET_ERROR) { closesocket(ConnectSocket); ConnectSocket = INVALID_SOCKET; continue; } break; } //u_long iMode = 1;//如果设置为0,为阻塞式的 //ioctlsocket(ConnectSocket, FIONBIO, &iMode); cout << "Connect Success!" << endl; freeaddrinfo(result); if (ConnectSocket == INVALID_SOCKET) { printf("Unable to connect to server!\n"); WSACleanup(); return 1; } Datablock resu_data; while (true) { //存储接收的字符 int len = recv(ConnectSocket, recvbuf, sizeof(recvbuf), 0); //通过连接套接字接收数据 //cout << "connect" << endl; if (len > 0) { vector<string>result; cout << "客户说:" << recvbuf << endl; string test = recvbuf; cout << test << endl; splitEx(result, test, "~"); test = result[0]; resu_data.m1 = str_float(result[1]); resu_data.m2 = str_float(result[2]); resu_data.m3 = str_float(result[3]); resu_data.m_roll = str_float(result[4]); resu_data.m_pitch = str_float(result[5]); resu_data.m_rotate = str_float(result[6]); cout << result[0] << endl; cout << resu_data.m1 << endl; cout << resu_data.m2 << endl; cout << resu_data.m3 << endl; cout << resu_data.m_roll << endl; cout << resu_data.m_pitch << endl; cout << resu_data.m_rotate << endl; memset(recvbuf, 0, sizeof(recvbuf)); } } return 0; }