首页 > 编程语言 >socket通信编程C++实现

socket通信编程C++实现

时间:2022-11-23 11:56:02浏览次数:72  
标签:socket int 编程 C++ char str sthread include SOCKET

socket提供了套接字,以方便我们想读取文件一样进行网络进程间的数据通信。

在网络通信中,套接字一定是成对出现的。一端的发送缓冲区对应对端的接收缓冲区。我们使用同一个文件描述符索发送缓冲区和接收缓冲区。

服务器端的一对多代码实现:

(14条消息) 用C++实现简单的一对多Socket通讯(二)_two L的博客-CSDN博客_c++ socket 一对多

源码已经封装好了,比较好,是面向对象的。但是面向过程上不易读,我稍作修改。

#include <iostream>
#include <WinSock2.h>
#include <vector>
#include <thread>
#include <mutex>
#pragma comment(lib,"ws2_32.lib")
#pragma warning(disable:4996)


typedef struct serverThread
{
    std::thread *t1 = nullptr;
    bool isRuning = false;
    int threadID = -1;
    SOCKET csocket = -1;
}Sthread;

void ThreadClientRecv(Sthread *sthread)
{
    while (sthread->isRuning == true)
    {
        // 从客户端接收数据
        char buff[65535];
        int nRecv = recv(sthread->csocket, buff, 65535, 0);//从客户端接受消息
        if (nRecv > 0)
        {
            char str[50];
            sprintf_s(str, "%dthread send message", sthread->threadID);
            char mess[] = "server:收到了你的消息。";
            send(sthread->csocket, mess, sizeof(mess), 0);
        }
        else
        {
            char str[50];
            sprintf_s(str, "ID%d is exit", sthread->threadID);
            sthread->isRuning = false;
        }
    }
    return;
}

int main()
{
    WSADATA wsaData;
    if (WSAStartup(MAKEWORD(2, 2), &wsaData) != 0)
        std::cout<<"Socket版本错误";

    SOCKET m_nServerSocket = socket(AF_INET, SOCK_STREAM, IPPROTO_TCP);    //设定TCP协议接口;失败返回INVALID_SOCKET
    if (m_nServerSocket == INVALID_SOCKET)
    {
        return 0;
    }

    int nRet = -1;
    if (m_nServerSocket != -1)
    {
        sockaddr_in Serveraddr;
        memset(&Serveraddr, 0, sizeof(sockaddr_in*));
        Serveraddr.sin_family = AF_INET;
        Serveraddr.sin_addr.s_addr = inet_addr("192.168.1.107");
        Serveraddr.sin_port = htons(1111);
        nRet = bind(m_nServerSocket, (sockaddr *)&Serveraddr, sizeof(Serveraddr));    //绑定服务器地址和端口号;成功,返回0,否则为SOCKET_ERROR
    }

    if (nRet == SOCKET_ERROR)
    {
        std::cout<<"绑定IP和端口失败"<<std::endl;
        return 0;
    }

    if (m_nServerSocket != -1)
    {
        nRet = listen(m_nServerSocket, 5);//设定接受连接的套接字,以及设定连接队列长度;成功返回0,失败返回-1
    }
    if (nRet == SOCKET_ERROR)
    {
        std::cout << "监听绑定失败"<<std::endl;
        return false;
    }
    std::vector<Sthread*> m_Vecthread;
    static int m_CsocketCount = 0;
    while (m_nServerSocket != -1)
    {
        sockaddr_in nClientSocket;//如果要保存客户端的IP和端口号,就存在本地
        int nSizeClient = sizeof(nClientSocket);
        SOCKET sClient = accept(m_nServerSocket, (sockaddr*)&nClientSocket, &nSizeClient);//接受客户端连接,阻塞状态;失败返回-1
        if (sClient == SOCKET_ERROR)
        {
            std::cout<<"当前与客户端连接失败"<<std::endl;
            return 0;
        }
        else
        {
            Sthread *it = new Sthread();
            it->threadID = ++m_CsocketCount;
            it->isRuning = true;
            it->csocket = sClient;
            std::thread t(ThreadClientRecv,it);
            t.detach();
            it->t1 = &t;
            m_Vecthread.push_back(it);
            char str[50];
            sprintf_s(str, "%dthread connect is success", it->threadID);

            char mess[] = "sercer:与服务器连接成功!";
            send(sClient, mess, sizeof(mess), 0);//发送消息给客户端
        }
        Sleep(25);
    }

    closesocket(m_nServerSocket);
    WSACleanup();
    return true;
}

我贴一张自己写的UDP的客户端

#include <WinSock2.h>
#include <iostream>
#pragma comment(lib,"ws2_32.lib")
#pragma warning(disable:4996)


int main()
{
    WORD wVersion = MAKEWORD(2, 2);
    WSADATA wsadata;
    if (WSAStartup(wVersion, &wsadata) != 0)
    {
        return 0;
    }
    //反初始化操作
    
    

    SOCKET s = socket(AF_INET, SOCK_DGRAM, 0);
    //第一个参数协议簇(AF_INET,ipv4;AF_INET6,ipv6;AF_UNIX,本机通信)
    //第二个参数类型(SOCK_STREAM,TCP流;SOCK_DGRAM,UDP数据报;SOCK_RAW,原始套接字)
    //第三个参数一般设置0,当确定套接字使用的协议簇和类型时,这个参数的值就为0      
    if (s == INVALID_SOCKET)
    {
        return 0;//创建套接字失败
    }
    sockaddr_in add;
    int len = sizeof(sockaddr_in);
    add.sin_family = AF_INET;//协议簇
    add.sin_addr.S_un.S_addr = inet_addr("192.168.1.107");//主动连接该ip地址
    add.sin_port = htons(11111);//网络字节序是大尾方式,本地字节序是小尾方式,需要转换
    int i = connect(s, (sockaddr*)&add, len);
    if (SOCKET_ERROR == i)
    {
        return 0;
    }

    while (true)
    {
        char sbuf[256] = { 0 };
        int ret = recv(s, sbuf, 256, 0);
        if (ret == 0)
        {
            break;//连接断开
        }
        else if (ret > 0)
        {
            std::cout<<sbuf;
        }
    }
    closesocket(s);
    WSACleanup();
}

 

标签:socket,int,编程,C++,char,str,sthread,include,SOCKET
From: https://www.cnblogs.com/xmds/p/16917814.html

相关文章