我是QT / C ++服务器和Java客户端。 客户端向服务器请求文件,服务器向客户端发送流。 问题是在TCP传输(也在localhost中)我丢失了一些数据包。 有时,客户端收到280705字节的288890。
有服务器:
MyTcpServer::MyTcpServer(QObject *parent) :
QTcpServer(parent)
{
}
void MyTcpServer::startServer(int port)
{
if(!this->listen(QHostAddress::Any, serverPort))
{
qDebug() << "Could not start server";
}
else
{
qDebug() << "Listening to port " << serverPort << "...";
}
}
void MyTcpServer::incomingConnection(qintptr socketDescriptor)
{
SocketThread *thread = new SocketThread(socketDescriptor, this);
connect(thread, SIGNAL(finished()), thread, SLOT(deleteLater()));
thread->start();
}
这是SocketThread:
SocketThread::SocketThread(qintptr ID, QObject *parent) :
QThread(parent)
{
this->socketDescriptor = ID;
}
void SocketThread::run()
{
socket = new QTcpSocket();
if(!socket->setSocketDescriptor(this->socketDescriptor))
{
emit error(socket->error());
return;
}
connect(socket, SIGNAL(readyRead()), this, SLOT(readyRead()), Qt::DirectConnection);
connect(socket, SIGNAL(disconnected()), this, SLOT(disconnected()));
socket->write("Welcome to the Server\r\n"); //SEND AN HELLO MESSAGE
socket->waitForBytesWritten();
exec();
}
void SocketThread::readyRead()
{
QByteArray socketByteArray = socket->readAll();
int number = 0;
QDataStream socketDataStream(socketByteArray);
socketDataStream >> number; //RECEIVE A NUMBER (I WANT 1)
if (number == 1)
{
QFile file("C:\\temp\\test.txt");
file.open(QIODevice::ReadWrite);
socket->write(QString("%1\n").arg(file.size()).toStdString().c_str()); //SEND THE FILESIZE AS STRING
socket->waitForBytesWritten();
QByteArray buffer = file.readAll();
long byteSent = socket->write(buffer); //SEND THE FILE
socket->flush();
file.close();
}
socket->close();
}
void SocketThread::disconnected()
{
socket->deleteLater();
exit(0);
}
这是JAVA客户端:
Socket MyClient = null;
boolean connect()
{
try
{
MyClient = new Socket(remoteIP, remotePort);
MyClient.setSoTimeout(60000);
if (MyClient != null) {
inFromServer = new BufferedReader(new InputStreamReader(MyClient.getInputStream()));
serverWelcomeMessage = inFromServer.readLine(); //RECEIVE THE WELCOME MESSAGE
}
}
catch (IOException e) {
...
}
}
void requestFile()
{
try {
FileOutputStream fos = null;
BufferedOutputStream bos = null;
DataOutputStream outToServer = new DataOutputStream(MyClient.getOutputStream());
outToServer.write(encodeIntToByteArray(1)); //SEND THE 1
outToServer.flush();
InputStream is = MyClient.getInputStream();
int remoteFileSize = Integer.parseInt(inFromServer.readLine()); //RECEIVE THE FILESIZE AS STRING
fos = new FileOutputStream(output);
bos = new BufferedOutputStream(fos);
int byteCount = 0;
int totalByteCount = 0;
byte[] bytes = new byte[1400];
while ((byteCount = is.read(bytes)) > 0) { //RECEIVE THE FILE
bos.write(bytes, 0, byteCount);
totalByteCount += byteCount;
}
System.out.println("Byte Received "+totalByteCount+" of "+remoteFileSize);
bos.close();
fos.close();
is.close();
}
catch(...) {
} }
文件test.txt是一行文件,每行都有一个数字:
0
1
2
3
4
...much numbers...
50000
有时,客户端会收到整个文件,有时会收到没有第一部分的文件,如下所示:
60
1860
1861
1862
...much numbers...
50000
从60开始,跳到1860并结束到50000。
我尝试迭代请求1000次,代码工作的90%,传输所有数据。
有人可以帮助我理解吗?
答案 0 :(得分:0)
问题在于使用IO流。如果没有正确理解副作用,就不能使用不同的实例:inFromServer&amp;是。您确切的问题是java.io.BufferedReader#defaultCharBufferSize。
我建议你初始化流和&amp;读者关于联系。并且在全班同学中使用它们。
private Socket socket;
private OutputStream outputStream;
private Writer outputWriter;
private InputStream inputStream;
private Reader inputReader;
public void connect() throws IOException {
socket = new Socket(..., ...);
socket.setSoTimeout(60000);
outputStream = new BufferedOutputStream(socket.getOutputStream()); // Buffered
outputWriter = new OutputStreamWriter(outputStream); // Non-buffered - !important
inputStream = new BufferedInputStream(socket.getInputStream()); // Buffered
inputReader = new InputStreamReader(inputStream); // Non-buffered - !important
}
最好使用Java代码的Java命名约定。