对于接收端来说,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()
}
欢迎分享,转载请注明来源:内存溢出
评论列表(0条)