windows TcpClinet 代码

文章介绍了如何在C++中使用Winsock库创建TCPSocket,包括初始化、连接服务器、发送数据、接收数据以及在接收数据部分使用QThread进行异步处理。

摘要生成于 C知道 ,由 DeepSeek-R1 满血版支持, 前往体验 >

头文件

#ifndef TCPSOCKET_H
#define TCPSOCKET_H
#include <windows.h>                      //windows socket
#include <winsock2.h>                     //windows socket 头文件
#include <QThread>
class RecvThread:public QObject
{
    Q_OBJECT
public:
    SOCKET *tcpSpcket;
    bool bRun=true;
    RecvThread();
    virtual ~RecvThread();
public slots:
    void Recv();
signals:
    void ToRecv();
    void ToShow(QString);
};

class TcpSocket
{
public:
    TcpSocket();
    virtual ~TcpSocket();
    void SetSocketNoblock();
    void connectToServer();
    void CloseSocket();
    void Send(QByteArray data);
    SOCKET tcpSpcket;
    sockaddr_in remoteAddr;
    bool connected=false;
    QThread recvThread;
    RecvThread recvThreadObject;
};




#endif // TCPSOCKET_H
cpp
#include "tcpsocket.h"
#include <QDebug>
TcpSocket::TcpSocket()
{
    //win socket 初始化
    WORD sockVersion=MAKEWORD(2,2);
    WSADATA wsaData;
    if(WSAStartup(sockVersion,&wsaData)!=0)
    {
        qDebug()<<"ERROR"<<__FUNCTION__<<__LINE__;
    }
    else
    {
        qDebug()<<"SUCESS"<<__FUNCTION__<<__LINE__;

    }



    //启动接收子线程
    recvThreadObject.moveToThread(&recvThread);
    recvThread.start(QThread::HighPriority);
    emit recvThreadObject.ToRecv();

}

TcpSocket::~TcpSocket()
{
    qDebug()<<__LINE__;
    recvThreadObject.bRun=false;
    SetSocketNoblock();
    recvThread.quit();
    recvThread.wait();
    CloseSocket();
}

void TcpSocket::SetSocketNoblock()
{
    u_long argp = 1;
    ioctlsocket(tcpSpcket, FIONBIO, &argp);
}

void TcpSocket::connectToServer()
{
    qDebug()<<"123456";
    //申请socket
    if(!connected)

    {
        tcpSpcket = socket(AF_INET, SOCK_STREAM, IPPROTO_TCP);
        //使用端口服用技术
        int opt=1;
        setsockopt(tcpSpcket,SOL_SOCKET,SO_REUSEADDR,(const char *)&opt,sizeof (opt));

        struct linger myLinger;
        myLinger.l_onoff=1;
        myLinger.l_linger=0;
        setsockopt(tcpSpcket,SOL_SOCKET,SO_LINGER,(const char *)&myLinger,sizeof (myLinger));

        //客户端指定端口与服务端通信
        struct sockaddr_in client_addr;
        client_addr.sin_addr.s_addr = htonl(INADDR_ANY);
        client_addr.sin_family = AF_INET;
        client_addr.sin_port = htons(60000);
        bind(tcpSpcket,(struct sockaddr *)(&client_addr),sizeof (sockaddr));


        //将socket设置成阻塞模式
        u_long argp = 1;
        qDebug()<<ioctlsocket(tcpSpcket, FIONBIO, &argp);

        //设置缓冲大小
        int recvBufSize=2592*2048*7;
        setsockopt(tcpSpcket,SOL_SOCKET,SO_RCVBUF,(const char *)&recvBufSize,sizeof(int));

        //设置接收超时
        int time=500;
        setsockopt(tcpSpcket,SOL_SOCKET,SO_RCVTIMEO,(char*)&time,sizeof(int));

        //设置要链接的TcpServer
        remoteAddr.sin_addr.S_un.S_addr=inet_addr("192.168.1.2");
        remoteAddr.sin_port=htons(60000);
        remoteAddr.sin_family=AF_INET;

        //将socket传输到子线程
        recvThreadObject.tcpSpcket=&tcpSpcket;

        int ret=connect(tcpSpcket, (SOCKADDR*)&remoteAddr, sizeof(SOCKADDR));
        if(ret==0)
        {
            connected=true;
        }
    }
}

void TcpSocket::CloseSocket()
{

    closesocket(tcpSpcket);
    QThread::msleep(500);
    connected=false;
    // shutdown(tcpSpcket,SD_BOTH);
}

void TcpSocket::Send(QByteArray data)
{
    send(tcpSpcket,data.toStdString().c_str(),data.length(),0);
}

RecvThread::RecvThread()
{
    connect(this,SIGNAL(ToRecv()),this,SLOT(Recv()));
}

RecvThread::~RecvThread()
{
    qDebug()<<__LINE__;
    bRun=false;
    QThread::msleep(1);
}

void RecvThread::Recv()
{
    char buf[1024]={0};
    sockaddr sin;
    int formLen=sizeof (sin);

    while (bRun)
    {
        memset(buf,0,1024);
        qDebug()<<"123:"<<tcpSpcket;
        int recvLen=  recvfrom(*tcpSpcket,(char*)buf,1024,0,&sin,&formLen);
        if(recvLen>0)
        {
            emit ToShow(buf);
            qDebug()<<"123456";
        }
    }
}

使用方法:

在mainWindows中声明TcpSocket类。然后调用Tcp的connectToServer,Send(DATA),CloseSocket()
方法使用
评论 1
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值