当前位置:编程学习 > wap >>

QT 里面用win32的socket,怎么设置非阻塞,把DATA传回给线程A

我的流程如下:
1:创建2个线程,ui通过emit传data给threadA
2:threadA通过socket把data传给threadB
3:threadB接收data后,添加几个字符后,再通过socket把data传回给threadA
4:threadA打印接收回来的data
5:threadA再通过emit传添加字符后的data给ui显示。
我的代码如下:

widget.cpp:
#include "widget.h"
#include "ui_widget.h"
#include <QtWidgets/QMainWindow>
#include <QtNetwork>
#include <QTcpServer>
#include <QString>
#include <QDebug>
#include <QWidget>

#define DEBUG_F_L(info) {qWarning("\n##file:%s\n; line:%d function:%s\n",__FILE__,__LINE__,__func__);qWarning info;}

Widget::Widget(QWidget *parent) :
    QWidget(parent),
    ui(new Ui::Widget)
{

    ui->setupUi(this);




    threadc = new QthreadC;
    threadc->start();

    threadb = new QthreadB;
    threadb->start();

}

Widget::~Widget()
{
    delete ui;
}



void Widget::on_pushButton_clicked()
{
    QString str = ui->lineEdit->text();
    qDebug() <<  str;
    const char *ch;
    QByteArray ba = str.toLatin1().data();
    ch = ba.data();

    char* pc = new char[256];
//    DEBUG_F_L(("ch = %s\n",ch));
    strcpy(pc,ch);
//    DEBUG_F_L(("pc = %s\n",pc));
    qDebug() << pc;
    connect(this,SIGNAL(to_qthreada(char*)),threadc,SLOT(recv_widget(char*)));
    emit  to_qthreada(pc);
}



qthreadc.cpp:

#include "qthreadc.h"
#include<stdio.h>
#include<stdlib.h>
#include<WinSock2.h>
#include<windows.h>
#include<winsock.h>
#include<string.h>
#include <QDebug>



#define PORT 2046
#define BACKLOG 10
#define TRUE 1


#define DEBUG_F_L(info) {qWarning("\n##file:%s\n; line:%d function:%s\n",__FILE__,__LINE__,__func__);qWarning info;}

#pragma comment(lib,"WS2_32.Lib")

QthreadC::QthreadC(QObject *parent) :
    QThread(parent)
{


}
QthreadC::~QthreadC()
{
}
void QthreadC::run()
{

    int iServerSock = -1;
    int iClientSock = -1;

    struct sockaddr_in ServerAddr;
    struct sockaddr_in ClientAddr;
    pc_c[256] = {0};
    int sin_size;
    int ret  ;
//    int flag = -1;//注意别重载的flag
    flag = -1;
    WSADATA WSAData;

    if( WSAStartup( MAKEWORD( 1, 1 ), &WSAData ) )//初始化
    {
        DEBUG_F_L(("initializationing error!\n"));
        WSACleanup( );
        exit( 0 );
    }
    while(1)
    {
        if(iServerSock == -1)
        {
            if((iServerSock = socket(AF_INET, SOCK_STREAM, 0)) == INVALID_SOCKET)
            {

                DEBUG_F_L(("socket error!\n"));
                WSACleanup();
                exit(0);
            }

            DEBUG_F_L(("iServerSock = %d\n",iServerSock));
            //设置非阻塞方式连接
//                unsigned long ul = 1;
//                ret = ioctlsocket(iServerSock, FIONBIO, (unsigned long *)&ul);
//                if (ret == SOCKET_ERROR)
//                {
//                    DEBUG_F_L(("ioctlsocket error!"));
//                    WSACleanup();
//                    exit( 0 );
//                }

            ServerAddr.sin_family = AF_INET;
            ServerAddr.sin_port = htons( PORT );//监视的端口号
            ServerAddr.sin_addr.s_addr = INADDR_ANY;//本地IP

            memset( & ( ServerAddr.sin_zero ), 0, sizeof( ServerAddr.sin_zero ) );


            if( bind( iServerSock, ( struct sockaddr * )&ServerAddr, sizeof( struct sockaddr ) ) == -1 )
            {

                DEBUG_F_L(("bind error!\n"));
                WSACleanup( );
                exit( 0 );
            }

            if( listen( iServerSock, BACKLOG ) == -1 )
            {

                DEBUG_F_L(("listen error!\n"));
                WSACleanup( );
                exit( 0 );
            }

        }
        sin_size = sizeof( struct sockaddr_in );
        if(iClientSock == -1)
        {
            iClientSock = accept( iServerSock, ( struct sockaddr * )&ClientAddr, &sin_size );
            DEBUG_F_L(("iClientSock = %d\n",iClientSock));
            if( iClientSock == -1 )
            {

                DEBUG_F_L(("accept error\n"));
                WSACleanup( );
                continue;
            }

        }
        if(flag == 1)
        {
            char *p;

            strcpy(p , pc_c);
//             DEBUG_F_L(("p = %s\n",p));
//                DEBUG_F_L(("pc_c = %s\n",pc_c));

            if( send(iClientSock, p,strlen(p), 0) == -1 )
            {

                DEBUG_F_L(("send error!\n"));
                closesocket( iClientSock );
                WSACleanup( );
                exit( 0 );
            }
            else
            {
                sleep(1);
             DEBUG_F_L(("p2 = %s\n",p));
            }
            flag = -1;
        }
    }
}

void QthreadC::recv_widget(char *pc)
{
    DEBUG_F_L(("qc_pc = %s\n",pc));
    if(pc != NULL)
    strcpy(pc_c,pc);
    flag = 1;
    DEBUG_F_L(("qc_pc = %s\n",pc_c));

}


qthreadb.cpp:

#include "qthreadb.h"
#include<stdio.h>
#include<stdlib.h>
#include<WinSock2.h>
#include<windows.h>
#include<winsock.h>
#include<string.h>



#define PORT 2046
#define BACKLOG 10
#define TRUE 1
#define MAXDATASIZE 256




#include <QDebug>

#define DEBUG_F_L(info) {qWarning("\n##file:%s\n; line:%d function:%s\n",__FILE__,__LINE__,__func__);qWarning info;}

#pragma comment(lib,"WS2_32.Lib")

QthreadB::QthreadB()
{

}
QthreadB::~QthreadB()
{
}
void QthreadB::run()
{


        int iClientSock = -1;        
        struct sockaddr_in ServerAddr;
        int numbytes ;
//        int ret;

        WSADATA WSAData;

        if( WSAStartup( MAKEWORD( 1, 1 ), &WSAData ) )//初始化
        {
            DEBUG_F_L(( "initializationing error!\n" ));
            WSACleanup( );
            exit( 0 );
        }
        while(1)
        {
            if(iClientSock == -1)
            {
                iClientSock = socket(AF_INET, SOCK_STREAM, 0);
//                DEBUG_F_L(("iClientSock = %d\n",iClientSock));
                if(iClientSock == INVALID_SOCKET)
                {
//                    DEBUG_F_L(( "iClientSock error\n" ));
                    WSACleanup();
                    exit(0);
                }
//                //设置非阻塞方式连接
//                    unsigned long ul = 1;
//                    ret = ioctlsocket(iClientSock, FIONBIO, (unsigned long*)&ul);
//                    if (ret == SOCKET_ERROR)
//                    {
//                        DEBUG_F_L(("ioctlsocket error!"));
//                        WSACleanup( );
//                        exit( 0 );
//                    }


                ServerAddr.sin_family = AF_INET;
                ServerAddr.sin_port = htons( PORT );
//                ServerAddr.sin_addr = *( ( struct in_addr * )host->h_addr );
                ServerAddr.sin_addr.s_addr = inet_addr("192.168.0.25");//记得换IP
                memset( &( ServerAddr.sin_zero ), 0, sizeof( ServerAddr.sin_zero ));
//                DEBUG_F_L(("\n"))
                if(::connect( iClientSock, ( struct sockaddr * ) & ServerAddr, sizeof( struct sockaddr ) ) == -1 )
                {
                    DEBUG_F_L(("connect error!"));
                    WSACleanup();
                    continue;
                }
            }
            char buf[256];
           // char buf[256];
            numbytes = recv(iClientSock, buf, 256, 0 );
            if( numbytes == -1 )
            {
                DEBUG_F_L( ("recv error!") );
                WSACleanup();

            }
            else if( numbytes == 0)
            {
                closesocket( iClientSock );
                WSACleanup() ;
                DEBUG_F_L( ("numbytes == 0") );
                iClientSock = -1;
            }

            else
            {

                buf[ numbytes ] = '\0';
                char STB[256] = {0},str[256] = "####";
                memcpy(STB,str,4);
//                DEBUG_F_L(("STB: %s", STB));
                memcpy(STB+4,buf,numbytes);
//                DEBUG_F_L(("STB: %s", STB));
                memcpy(STB+4+numbytes,str,4);
//                DEBUG_F_L(("STB: %s", STB));
//                DEBUG_F_L(("Received: %s", buf));
                memset(buf, 0, sizeof(buf));
                //closesocket( iClientSock );
//                WSACleanup( ) ;
//                iClientSock = -1;
//                if( send(iServerSock, STB,strlen(STB), 0) == -1 )
//                {

//                    DEBUG_F_L(("send error!\n"));
//                    closesocket( iServerSock );
//                    WSACleanup( );
//                    exit( 0 );
//                }
//                else
//                {
//                    sleep(1);
//                 DEBUG_F_L(("STB = %s\n",STB));
//                }
            } 

         }


}

main.cpp:

#include "widget.h"
#include <QTextCodec>
#include <QApplication>


int main(int argc, char *argv[])
{

    QApplication a(argc, argv);
    QTextCodec::setCodecForLocale(QTextCodec::codecForName("GB18030"));
    Widget w;
    w.show();

    
    return a.exec();
}




UI:




那个非阻塞,一开就卡死,到底错在哪?B线程怎么样才能把DATA回传给A --------------------编程问答-------------------- 楼主是不是没有进行过win32程序开发啊,WinSock有套接字模型的,你用的阻塞模型,所以卡,你可以找找,WinSock有6中IO模型,第一个是阻塞,其他的都是非阻塞:select, WSAAsyncSelect, WSAEventSelect, 重叠模型,IO完成端口模型,可以网上找找
补充:移动开发 ,  Qt
CopyRight © 2012 站长网 编程知识问答 www.zzzyk.com All Rights Reserved
部份技术文章来自网络,