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;
}

 

posted on 2017-08-11 14:34  Sketch_kai  阅读(1172)  评论(0编辑  收藏  举报