为什么CSOcket接收信息会卡住

为什么CSOcket接收信息会卡住,第1张

楼主可能没搞清楚,当每个socket建立后会有一个发送缓冲区和一个接收缓冲区,windows系统默认是8KB,send调用成功以后数据并没有立即发出去,而只是把发送的数据复制到发送缓冲区,由 *** 作系统底层实现发送功能,发送到接受端的接收缓冲区。为了减轻网络负担,一般的TCP链接用了nagle算法,并不是发送缓冲区有数据就会发送的。

对于接收端来说,receive(char *buf,num)只是从接收缓冲区里面取数据,返回的值就是取得的数据大小。你多次send,如果数据量不大,而num的值超过了发送的总值,那么就会一次取完接受缓冲区的数据。

不知道这样解释楼主清楚了没有。

//你没有贴代码

//客户端代码

package com.dxy.SocketChat

import java.io.BufferedReader

import java.io.IOException

import java.io.InputStream

import java.io.InputStreamReader

import java.io.OutputStream

import java.io.PrintWriter

import java.net.Socket

import java.net.UnknownHostException

import javax.swing.JOptionPane

public class SocketClient {

 private Socket ClientSocket//给定一个私有的Socket

 

 public void ClientCall() throws IOException

 {

  //相当于电话拨号的一方

  //1.创建和服务器端的连接

  try {

   System.out.println("客户端启动")

   ClientSocket = new Socket("127.0.0.1",8888)

   InputStream in = ClientSocket.getInputStream()//用于接收的

   OutputStream os = ClientSocket.getOutputStream()//用于发送的

   String Text=JOptionPane.showInputDialog(null, "消息内容:", "输入", JOptionPane.DEFAULT_OPTION)

   os.write(Text.getBytes())

   PrintWriter pw =new PrintWriter(os)

   pw.println()

   pw.flush()

   

   BufferedReader br = new BufferedReader(new InputStreamReader(in))

   System.out.println("服务端发给你的消息:"+br.readLine())

   in.close()

   os.close()

   br.close()

   pw.close()

   ClientSocket.close()

  } catch (UnknownHostException e) {

   // TODO Auto-generated catch block

   e.printStackTrace()

  } catch (IOException e) {

   // TODO Auto-generated catch block

   e.printStackTrace()

  }

 }

 

 public static void main(String[] args) throws IOException {

  new SocketClient().ClientCall()

 }

}

//服务器端代码

package com.dxy.SocketChat

import java.io.BufferedReader

import java.io.IOException

import java.io.InputStream

import java.io.InputStreamReader

import java.io.OutputStream

import java.io.PrintWriter

import java.net.ServerSocket

import java.net.Socket

import javax.swing.JOptionPane

public class SocketServer {

 private ServerSocket serverSocket//给定一个私有的服务器端的socket

 

 /**

  * @throws IOException

  */

 public void Listen() throws IOException

 {

  serverSocket = new ServerSocket(8888)

  Socket sSocket=serverSocket.accept()//连接成功后会返回一个Socket

  System.out.println("客户端连接成功")

  InputStream in =sSocket.getInputStream()

  OutputStream os = sSocket.getOutputStream()

  BufferedReader br = new BufferedReader(new InputStreamReader(in) )

  System.out.println(br.readLine())

  String Text=JOptionPane.showInputDialog(null, "回复内容:", "输入", JOptionPane.DEFAULT_OPTION)

  os.write(Text.getBytes())

  PrintWriter pw = new PrintWriter(os)

  pw.println()

  pw.flush()

  in.close()

  os.close()

  br.close()

  pw.close()

  serverSocket.close()

 }

public static void main(String[] args) throws IOException {

  new SocketServer().Listen()

 }

}

使用方法1 继承QT thread 重写run

void DataUnpacket::run( )

{

    m_pSocket = new QTcpSocket

    //m_pSocket->socketOption(QAbstractSocket::LowDelayOption)

    QString ip("192.168.112.100")

    ushort portData = 5001

    m_pSocket->connectToHost( ip, portData )

    m_pSocket->waitForConnected()

    if( QAbstractSocket::ConnectedState != m_pSocket->state() )//判断是否连接成功

        return

    while( m_bRunning )

    {

        if( m_pSocket->bytesAvailable() >0)

        {

            QByteArray arr = m_pSocket->readAll()//这不进,

            qDebug() <<"recv len =" <<arr.length()

        }

        else

        {

            m_pSocket->write("test",4)

            m_pSocket->flush()// 可以发送出去

            QThread::usleep(1000)

        }

    }

}

方法二 movethred  效果 一样 

方法三 SocketQThread中使用  QtConcurrent::run创建线程, 这个使用QTCreater 调试没有问题,这个也是大坑

打包会出现不能接收到数据或者没发出去, wireshark检测有时会出现现象接收到数据但没发出去

int SocketQThread::InitTest( )

{

    int re = 0

    QString ip("192.168.112.5")

    ushort portData = 5001

    m_pDataPackage.resize(1)

    m_pDataPackage[0] = new DataUnpacket

   if( !m_pDataPackage[0]->InitSocket(ip,portData ) )

       re = -1

    return re

}

void SocketQThread::stratThred()

{

    m_running = true

    for(int i=0i<1i++)//测试

    {

      QtConcurrent::run(this, &SocketQThread::recvDataThread, i )

    }

}

void SocketQThread::stopThred()

{

    m_running = false

    for(int i=0i<1i++)//测试

    {

      m_pDataPackage[0]->CloseFile( )

      m_pDataPackage[0]->tcpDisconnect( )

    }

}

void SocketQThread::recvDataThread( int ch )//暂定

{

    DataUnpacket* pPackage = m_pDataPackage[ch]

    while( m_running )

    {

        if( pPackage->SocketBytesAvailable() >0)

            pPackage->RecvData()

        else

            QThread::usleep(1)

    }

}

类DataUnpacket 继承 Cpackage 如下:

m_Socket为Cpackage的成员变量

int DataUnpacket::RecvData( )

{

    int re = 0

    QByteArray reArr

    QByteArray arr = m_Socket.readAll()

   qDebug() <<"recv len =" <<arr.length()

    #if 0

    m_Socket.write(arr )

    m_Socket.flush()//不加发不出去

#else

    QMetaObject::invokeMethod( &m_Socket, std::bind( static_cast<qint64(QTcpSocket::*)(const QByteArray &) >( &QTcpSocket::write ),&m_Socket, arr ))//, Qt::DirectConnection

    //若加 Qt::DirectConnection ,需要添加m_Socket.flush()/

    return re

}

bool Cpackage::InitSocket(QString&ip, ushort&port )

{

    bool tf = true

    m_Socket.connectToHost( ip, port )

    m_Socket.waitForConnected()

    if( QAbstractSocket::ConnectedState != m_Socket.state() )//判断是否连接成功

        tf = false

    return tf

}

void Cpackage::tcpDisconnect( )

{

    if( m_Socket.state() == QAbstractSocket::ConnectedState)  //关闭时,确保与服务器断开连接

      m_Socket.disconnectFromHost()

}

方法四 QtConcurrent::run(this, &DataUnpacket::RecvDataTest)  这个

void testData::RecvDataTest()

{

    m_pSocket = new QTcpSocket(this)

    //m_pSocket->socketOption(QAbstractSocket::LowDelayOption)

    QString ip("192.168.112.100")

    ushort portData = 5001

    m_pSocket->connectToHost( ip, portData )

    m_pSocket->waitForConnected()

    if( QAbstractSocket::ConnectedState != m_pSocket->state() )//判断是否连接成功

        return

    while( m_bRunning )

    {

        if( m_pSocket->bytesAvailable() >0)

        {

            QByteArray arr = m_pSocket->readAll()//这不进,

            qDebug() <<"recv len =" <<arr.length()

        }

        else

        {

            m_pSocket->write("test",4)

            m_pSocket->flush()//可以发送出去

            QThread::usleep(1000)

        }

    }

}

如下例子 是可以的

void testData::RecvDataTest()

{

    qDebug() <<QThread::currentThread()

    QByteArray arr = m_pSocket->readAll()//这不进,

    qDebug() <<"recv len =" <<arr.length()

    m_pSocket->write("test",4)

}

void testData::stratThred( bool tf )

{

    if( tf )

        start()

    else

        exit()

}

void testData::run( )

{

    qDebug() <<"stratThred" <<QThread::currentThread()

    if( nullptr == m_pSocket )

    {

        m_pSocket = new QTcpSocket

        connect(m_pSocket, SIGNAL(readyRead()), this, SLOT(RecvDataTest()), Qt::DirectConnection)

        //m_pSocket->socketOption(QAbstractSocket::LowDelayOption)

    }

    m_pSocket->connectToHost( QString("192.168.112.100"), 5001 )

    m_pSocket->waitForConnected()

    if( QAbstractSocket::ConnectedState != m_pSocket->state() )//判断是否连接成功

        return

    //m_pSocket->waitForReadyRead(1000)

    exec()

    m_pSocket->disconnectFromHost()

}


欢迎分享,转载请注明来源:内存溢出

原文地址: http://outofmemory.cn/sjk/9852687.html

(0)
打赏 微信扫一扫 微信扫一扫 支付宝扫一扫 支付宝扫一扫
上一篇 2023-05-02
下一篇 2023-05-02

发表评论

登录后才能评论

评论列表(0条)

保存