Java 简单 TCP 客户端/服务器测试冻结

Posted

技术标签:

【中文标题】Java 简单 TCP 客户端/服务器测试冻结【英文标题】:Java simple TCP client/server test freezes 【发布时间】:2016-01-01 06:17:58 【问题描述】:

我正在尝试了解如何制作 java 服务器/客户端程序,但我不明白为什么它不起作用,即使我在单独的线程中运行循环,我的服务器界面也没有显示,我在某些时候设法得到端口错误,我什至不知道该尝试什么,所以这里是代码: (我在一台计算机上执行了这两个程序)

我做错了什么?

客户:

    import java.awt.Dimension;
import java.awt.event.ActionEvent;
import java.awt.event.ActionListener;
import java.io.BufferedReader;
import java.io.DataOutputStream;
import java.io.IOException;
import java.io.InputStreamReader;
import java.net.Socket;
import java.net.UnknownHostException;

import javax.swing.BoxLayout;
import javax.swing.JButton;
import javax.swing.JFrame;
import javax.swing.JLabel;
import javax.swing.JPanel;
import javax.swing.JTextField;


public class Client extends JFrame 

String sentence;
String modifiedSentence;
int port = 6791;

JTextField tf = new JTextField();
JButton valider = new JButton("Send");
JLabel retour = new JLabel("nothing");

Socket clientSocket;
DataOutputStream outToServer;
BufferedReader inFromServer;


public Client() throws UnknownHostException, IOException   

    this.setSize(200, 130);
    this.setDefaultCloseOperation(EXIT_ON_CLOSE);
    this.setTitle("Client");
    this.setResizable(false);




    JPanel zoneclient = (JPanel)getContentPane();

    Dimension d = new Dimension(300 , 25);
    tf.setPreferredSize(d);
    tf.setMaximumSize(d);
    retour.setPreferredSize(d);
    valider.setPreferredSize(d);

    zoneclient.setLayout(new BoxLayout(zoneclient, BoxLayout.Y_AXIS));
    zoneclient.add(new JLabel("Client"));
    zoneclient.add(tf); 
    zoneclient.add(retour);
    zoneclient.add(valider);



    valider.addActionListener(new appActionListener());








class appActionListener implements ActionListener

    @Override
    public void actionPerformed(ActionEvent e) 
        // TODO Auto-generated method stub
        sentence = tf.getText();

        try 

            BufferedReader inFromUser = new BufferedReader(new InputStreamReader(System.in));



            clientSocket = new Socket("localhost", port);
            clientSocket.setReuseAddress(true);

            outToServer = new DataOutputStream(clientSocket.getOutputStream());
            inFromServer = new BufferedReader(new InputStreamReader(clientSocket.getInputStream()));
         catch (Exception f) 
            // TODO: handle exception
            System.out.println("connexion failed");
        

        try 
            outToServer.writeBytes(sentence + '\n');
            modifiedSentence = inFromServer.readLine();
            retour.setText(modifiedSentence);
            clientSocket.close();
         catch (IOException e1) 
            // TODO Auto-generated catch block
                e1.printStackTrace();
                tf.setText("error");
            

        




这是服务器:

    package server;

import java.awt.Dimension;
import java.io.BufferedReader;
import java.io.DataOutputStream;
import java.io.IOException;
import java.io.InputStreamReader;
import java.net.ServerSocket;
import java.net.Socket;

import javax.swing.BoxLayout;
import javax.swing.JFrame;
import javax.swing.JLabel;
import javax.swing.JPanel;

class MyServer extends JFrame

    ServerSocket welcomeSocket;

    String clientSentence;
    String capitalizedSentence;
    JLabel retour = new JLabel("nothing");

    public MyServer() throws IOException

        System.out.println("server started");
        this.setSize(200, 130);
        this.setDefaultCloseOperation(EXIT_ON_CLOSE);
        this.setTitle("Server");
        this.setResizable(false);

        JPanel zoneclient = (JPanel)getContentPane();

        Dimension d = new Dimension(300 , 25);

        retour.setPreferredSize(d);

        zoneclient.setLayout(new BoxLayout(zoneclient, BoxLayout.Y_AXIS));
        zoneclient.add(new JLabel("Server"));
        zoneclient.add(retour);


        welcomeSocket = new ServerSocket(6791);
        welcomeSocket.setReuseAddress(true);
        MyThread th = new MyThread();
        th.run();
    


    class MyThread extends Thread
        public void run()
            while (true) 
                Socket connectionSocket;
                try 
                    connectionSocket = welcomeSocket.accept();
                    BufferedReader inFromClient = new BufferedReader(new InputStreamReader(connectionSocket.getInputStream()));
                    DataOutputStream outToClient = new DataOutputStream(connectionSocket.getOutputStream());
                    clientSentence = inFromClient.readLine();
                    retour.setText("Received: " + clientSentence);
                    capitalizedSentence = clientSentence.toUpperCase();
                    outToClient.writeBytes(capitalizedSentence);
                 catch (IOException e) 
                    // TODO Auto-generated catch block
                    e.printStackTrace();
                    System.out.println("???");
                
            
        
    

【问题讨论】:

【参考方案1】:

问题是客户端代码等待来自服务器的换行符\n。由于您正在调用流的readLine

 modifiedSentence = inFromServer.readLine();

解决方案:

将你的服务器代码也改成\n,如下所示。

outToClient.writeBytes(capitalizedSentence+'\n');

注意:我认为你不需要 new BufferedReader(new nputStreamReader(System.in)) 里面的 actionPerformed()

【讨论】:

确实!就是这样,谢谢!但是你知道为什么我的服务器 GUI 没有显示吗? 以及为什么我每次运行 prog 时都必须更改端口,否则在线程“main”java.net.BindException 中出现异常:地址已在使用中:JVM_Bind? 好吧,没关系,作为一个白痴无助于擅长编程:我使用了 thread.run;而不是 thread.start();

以上是关于Java 简单 TCP 客户端/服务器测试冻结的主要内容,如果未能解决你的问题,请参考以下文章

Java案例:基于TCP的简单聊天程序

Java 通过实现简单的TCP通信程序来理解TCP通信

一个简单的JAVA服务器-客户端模型-tcp

Java中的简单TCP客户端/服务器程序

线程睡眠冻结了我的代码。 Java 客户端-服务器通信

java写tcp客户端测试类该怎么写