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