如何在java和TCP客户端中实现TCP服务器在cpp中传输字符串

时间:2016-07-12 14:06:10

标签: java c++ sockets tcp

我试图将一个简单的消息从作为客户端的覆盆子pi传输到我的计算机,即服务器。我使用cpp用于tcpClient而java用于tcpServer。 这是我的TCPServer.java:

import java.net.*;
import java.io.*;


class TCPServer extends Thread {

    TCPClass() {
    }

    public void connect(){
        try {
            ServerSocket welcomeSocket = new ServerSocket();
            welcomeSocket.setReuseAddress(true);
            welcomeSocket.bind(new InetSocketAddress(8080));

            System.out.println("server start listening... ... ...");

            Socket connectionSocket = welcomeSocket.accept();
            System.out.print("Server has connected!\n");
            Connection c = new Connection(connectionSocket);
            c.start();
            connectionSocket.close();
            welcomeSocket.close();
            System.out.println("connection terminated");
        }
        catch(IOException e) {
            System.out.println("Listen :"+e.getMessage());
        }
    }

    class Connection extends Thread{
        Socket connectionSocket;
        Connection(Socket _connectionSocket){
                connectionSocket = _connectionSocket;    
        }
        public void run(){
            try{
                BufferedReader inFromClient = new BufferedReader(new InputStreamReader (connectionSocket.getInputStream()));
                DataOutputStream outToClient = new DataOutputStream(connectionSocket.getOutputStream());
                String clientSentence = inFromClient.readLine();
                System.out.println("Client sent: "+clientSentence);

String capitalizedSentence = clientSentence.toUpperCase() + '\n';

                System.out.println("Client sent: "+capitalizedSentence);
                outToClient.writeBytes(capitalizedSentence);
                outToClient.flush();
                inFromClient.close();
            }catch(Exception e){}
        }
    }

这是我的TCPClient.cpp:

 #include "Client.h"
#include <QHostAddress>

Client::Client(QObject* parent): QObject(parent)
{
  connect(&client, SIGNAL(connected()),
    this, SLOT(startTransfer()));
}

Client::~Client()
{
  client.close();
}

void Client::start(QString address, quint16 port)
{
  QHostAddress addr(address);
  client.connectToHost(addr, port);
}

void Client::startTransfer()
{
  client.write("Hello, world", 13);
}

最后,这是执行我的TCPClient.cpp的程序:

#include "Client.h"
#include <QApplication>
#include <iostream>

int main(int argc, char** argv)
{
  QApplication app(argc, argv);

  Client client;
  std::cout << argv[1] << " " << argv[2] << std::endl;
  client.start( argv[1], atoi( argv[2] ) );
//  client.start("127.0.0.1", 8888);

  return app.exec();
}

所以我执行了我的TCPServer.java,我有一条消息来证明服务器已连接,所以我执行了我的TCPCLient.cpp,并且存在问题。我的服务器没有显示客户端发送的任何消息,但是当我结束TCPClient.cpp的执行时,屏幕上会显示消息,这表示服务器已收到消息。怪不! 谢谢你的帮助。

编辑: 这是我的Client.h,对不起延迟

// client.h
#include <QtNetwork>
#include <QObject>
#include <QString>
#include <QTcpSocket>

class Client: public QObject
{
Q_OBJECT
public:
  Client(QObject* parent = 0);
  ~Client();
  void start(QString address, quint16 port);
public slots:
  void startTransfer();
private:
  QTcpSocket client;
};

2 个答案:

答案 0 :(得分:3)

完全没有。您正在使用以下命令关闭服务器中的套接字:

connectionSocket.close();

刚启动线程后。因此,当线程开始执行时,它将使用一个封闭的套接字。请记住start()不等待线程终止(它在创建线程后立即返回)。在关闭所有内容之前,您必须让TcpServer等待Connection线程的终止。像这样更改代码:

 Connection c = new Connection(connectionSocket);
 c.start();
 c.join();  //add this line. It means: wait for the termination of c then proceed to closing the socket
 connectionSocket.close();

[更新]

此外,您需要在写完后刷新客户端(cpp部分):

client.write("Hello, world", 13);
client.flush();

答案 1 :(得分:0)

您永远不会等待对等方能够发送任何内容,并立即关闭连接,服务器端和客户端。在这样的用例中,你应该用纸和笔来写出你想要的东西:

  • 服务器侦听 - 等待连接
  • 客户端连接 - 服务器接受并读取一行 - &gt;服务器等待输入数据
  • 客户端发送一行并应等待确认 - &gt;客户端应等待输入数据
  • 服务器发送上层线路(即使它会被忽略)并发出信号表示已完成shutdown write关闭) - 它再次等待< em>确认并因此等待输入数据
  • 关闭导致客户端在读完所有答案后读取0长度

您现在确定对方已收到从一方发送的所有数据:客户端可以安全地关闭其套接字。服务器将获得0长度读取并将关闭其自己的套接字

这称为graceful shutdown,并保证在TCP连接中断之前,对方已收到一方发送的所有内容。