qt和java的socket连接

事先说明qt为客户端(发出请求)java为服务端(处理请求)
关于qt的客户端来说我们大体上要完成三个需求,即请求连接,发送,接收

  1. 请求连接

如果想使用qt写socket程序,首先需要在.pro文件中添加QT += network;(非常非常重要)

  1. 接收

然后我们就可以在代码中使用QT的网络库了,socket涉及到的函数库有Qtcpsocket,QTcpServer
下面为连接部分与接收部分代码:

void MainWindow::on_le_ip_textChanged(const QString &arg)//定义了一个lineEdit(用于输入ip地址)
{
    ip=arg;//ip为全局变量
}

void MainWindow::on_le_port_textChanged(const QString &arg1)//定义了一个lineEdit(用于输入端口号)
{
    port=arg1.toInt();//port为全局变量
}
 void MainWindow::on_pb_con_clicked()//定义了一个按钮(点击进行socket连接)
{
    socket->connectToHost(ip,port);//请求socket连接(你要保证服务端提前开启,下面再说)
    //下面定义了三个槽函数,什么是槽函数呢,当socket连接成功后会发出名字叫做connected的信号发送给this中的forbid函数(自己定义的槽函数),this指向的是MainWindow类,forbid是MainWindow类的一个槽函数(有点生疏,还请见谅)
    connect(socket,SIGNAL(connected()),this,SLOT(forbid()));//connected()为连接成功的信号
    connect(socket,SIGNAL(readyRead()),this,SLOT(read()));//readyRead()为有数据可读的信号
    connect(socket,SIGNAL(disconnected()),this,SLOT(unforbid()));//disconnected()为连接失败的信号


}
void MainWindow::read(){//读取数据
//当服务端发来数据时接收所有数据并显示在textEdit中
    QString message=socket->readAll();
    ui->textEdit->append(message);
}
void MainWindow::forbid(){
    //当连接成功的时获取ip和port的输入框禁止输入
    ui->le_ip->setEnabled(false);
    ui->le_port->setEnabled(false);

}

void MainWindow::unforbid(){
      //当连接失败或未连接的时获取ip和port的允许输入
    ui->le_ip->setEnabled(true);
    ui->le_port->setEnabled(true);


}
  1. 发送数据

在上面的代码中三个需求中的请求连接和接收已经完成,接下来就是发送数据了,发送数据需要用到QT中的QByteArray类,QByteArray类是QT中处理字节数组的类,代码如下:

void MainWindow::on_pb_send_clicked()
//定义了一个按钮(点击进行socket发送数据)
{QString mes=ui->textEdit_2->toPlainText();
//获取textEdit_2中的文本内容并转换成QByteArray类型
    socket->write(mes.toUtf8()+"\r\n");

}

对于发送来说我们只需要获取文本框中的内容,然后将其转换为QByteArray类型,最后调用socket的write函数发送数据即可


接下来就是java喽,在上面的qt中我们写了一个socket的客户端
向服务端发送了一个请求连接,现在我们就要去编写服务端咯
作为服务端我们需要先创建一个socket服务端,然后等待客户端的连接,当客户端连接成功后,服务端需要接收客户端发送的数据,然后将接收到的数据进行处理,最后将处理后的数据发送给客户端,代码如下:


public class socket {
    private ServerSocket socketserver;//socket服务端
    private int port;//端口号
    private BufferedReader in;//输入输出流
    private BufferedWriter out;
    //socket接口列表
    socketserver ssocket;
    List<Socket> slist = new ArrayList<>();

    public socket(int port) throws Exception {
        this.port = port;//获取端口号
        try {
            socketserver = new ServerSocket(this.port);//以获取到的端口号来创立服务器

        } catch (Exception e) {
            //TODO: handle exception
            e.printStackTrace();

        }
        while (true) {//由于java不像qt有槽函数机制所以java就要反复扫描,就相当于有个人一直在问:有人连接了吗,有人连接了吗(乐)
            try {//当有客户端连接是,创建一个新的连接对象并把它存到socket接口列表中
                System.out.println("等待连接");
                Socket socket = socketserver.accept();
                slist.add(socket);
                
             //确认是否连接成功,如果连接成功,就创立一个接口并向终端发送ip+端口号+连接成功
                if (socket.isConnected()) {
                    ssocket = new socketserver(socket);
                    ssocket.setSocketList(slist);
                    ssocket.start();

                    System.out.println(socket.getInetAddress().getHostAddress() + ":" + socket.getPort()+ "连接成功");

                }
                else {
                    socket.close();
                }

            } catch (IOException e) {
                e.printStackTrace();
                System.out.println("连接失败");
                //TODO: handle exception

            }

        }

    }



}
在java的服务端和qt的客户端建立连接后,我们就要准备有服务端向客户端进行收发的操作了。
代码如下:
//要在java的服务端中进行收发操作我们涉及到技术有多线程以及输入输出流

public class socketserver extends  Thread {
   BufferedWriter out;//定义输出流,用于输出操作
   BufferedReader in;//定义输入流,用于读取操作
   List<Socket> list;//socket接口列表,用于储存客户端连接的socket接口
   Socket socket;
  socketserver(Socket socket) {
     try {
       //在连接成功后初始化输入输出流(输出new一个对象hhh)并输出hello from server 表示连接成功,
   this.socket=socket;
        in = new BufferedReader(new InputStreamReader(socket.getInputStream()));
        out = new BufferedWriter(new OutputStreamWriter(socket.getOutputStream()));
        out.write("Hello from server");
        //newline()的意思是发送新行相当于\r\n了
        out.newLine();
        //刷新一下,让数据从缓存区域发送出去
        out.flush();
        
        //out.close();
     } catch (IOException e) {
        throw new RuntimeException(e);
     }

  }
   void setSocketList(List<Socket> list)
   {
       this.list = list;
   }


  @Override
//发送写完就该写接收了,但怎么接收是个问题,困难在于java没有像qt一样的槽函数,只能一直进行扫描知道有信息发过来,可java的主线程在一直进行连接操作无法进行读取操作一次我们就要进行多线程操作了,要进行多线程操作我们首先要继承一个类 Thread (java的线程类)关于它的解释可以自行查找
//我对于多线程的理解是:两段或者多段程序一起运行
  public void run() {//从写运行函数

     while (true) {//无线扫描,知道客户端发送信息
        try {
            in = new BufferedReader(new InputStreamReader(socket.getInputStream()));
            //读取客户端发送的信息
           String msg = in.readLine();
           System.out.println( msg);
            //循环列表中的所有端口,做到把收到信息除发送方以外全部发送一遍
           for(int i=0;i<list.size();i++){
               if(this.socket==list.get(i)){

                   continue;
               }
               BufferedWriter out1 = new BufferedWriter(new OutputStreamWriter(list.get(i).getOutputStream()));
               out1.write(msg);
               out1.newLine();
               out1.flush();

           }

        } catch (IOException e) {
           e.printStackTrace();
           throw new RuntimeException(e);

        }

     }
  }
}

以上就是一些在不同的编程语言中的socket连接(我写的很菜,哪里出错了的话还请各位大佬指正)

posted @ 2024-01-19 13:48  依羽  阅读(153)  评论(0)    收藏  举报