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

 

转载于:https://www.cnblogs.com/Sketch-liu/p/7345747.html

  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
实现局域网聊天系统可以使用C++Winsock库下面是一个简单的示例代码,示了如何使用Winsock库创建一个基的局域网聊天系统: ```cpp #include <iostream> #include <thread> #include <WinSock2.h> #pragma comment(lib, "ws2_32.lib") void ReadMessage(SOCKET clientSocket) { char buffer[4096]; while (true) { ZeroMemory(buffer, sizeof(buffer)); int bytesReceived = recv(clientSocket, buffer, sizeof(buffer), 0); if (bytesReceived <= 0) { std::cout << "Disconnected from server" << std::endl; break; } std::cout << "Received: " << buffer << std::endl; } } int main() { WSADATA wsaData; if (WSAStartup(MAKEWORD(2, 2), &wsaData) != 0) { std::cerr << "Failed to initialize winsock" << std::endl; return -1; } SOCKET clientSocket = socket(AF_INET, SOCK_STREAM, 0); if (clientSocket == INVALID_SOCKET) { std::cerr << "Failed to create socket" << std::endl; return -1; } sockaddr_in serverAddress{}; serverAddress.sin_family = AF_INET; serverAddress.sin_port = htons(54000); serverAddress.sin_addr.s_addr = inet_addr("127.0.0.1"); if (connect(clientSocket, reinterpret_cast<sockaddr*>(&serverAddress), sizeof(serverAddress)) == SOCKET_ERROR) { std::cerr << "Failed to connect to server" << std::endl; closesocket(clientSocket); WSACleanup(); return -1; } std::cout << "Connected to server" << std::endl; std::thread readThread(ReadMessage, clientSocket); char buffer[4096]; while (true) { std::string message; std::getline(std::cin, message); if (message == "exit") { break; } int bytesSent = send(clientSocket, message.c_str(), message.size() + 1, 0); if (bytesSent <= 0) { std::cerr << "Failed to send message" << std::endl; break; } } readThread.join(); closesocket(clientSocket); WSACleanup(); return 0; } ``` 此示例使用TCP协议进行通信。首先,它会尝试初始化Winsock库并创建一个客户端套接字。然后,它将尝试连接到指定的服务器地址和端口。如果连接成功,它会启动一个单独的线程用于接收来自服务器的消息。主线程将从标准输入读取用户输入,并将其发送到服务器。用户可以通过输入"exit"来退出聊天系统。 请注意,此示例仅为演示目的,并不包含错误处理和完整的功能。在实际应用中,您可能需要添加更多的错误检查和处理逻辑,并根据需要扩展代码。 希望这可以帮助您开始实现局域网聊天系统。如有任何疑问,请随时提问。

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

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

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值