【问题标题】:suggestions for separate threads for socket input and output对套接字输入和输出的单独线程的建议
【发布时间】:2011-12-03 10:40:31
【问题描述】:

我正在尝试在 java 中进行一些套接字编程。我所拥有的是,我编写了这个程序来在我的本地机器上创建一个服务器和客户端,并为套接字输入和输出创建单独的两个线程放在 Se.java 文件中。类似地,文件 Cl.java

中客户端的套接字输入和输出的两个单独线程

现在,当我编译它们时,它们都没有显示错误或异常,但是当我运行它时,出现一些异常的服务器继续运行,但客户端崩溃

我不知道哪里出了问题。我要做的就是为每个服务器和客户端创建两个线程,分别检查对套接字的读取和写入。任何建议都会很棒帮助

PS。对不起,如果问题太“noobie-ish”。请对我放轻松。这是我在这里的第一篇文章

这个相同的程序,在之前完美运行,当我在每个客户端文件 Cl.java 中只有一个线程来读取服务器输入并打印它,并在服务器端读取从客户端输入并打印。但是当我在每个服务器和客户端程序中创建两个线程来读取和写入字符串时,问题就来了。

任何建议都会受到欢迎。只是想在客户端和服务器端创建两个单独的线程用于读取和写入。

这是我的服务器完整代码:

Se.java

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

public class Se
{
    public static int i=0;

    public static BufferedReader stdIn =null;

    public static void main (String [] args) throws IOException
    {
        ServerSocket serverSocket = null ;

        try {
            serverSocket = new ServerSocket (4321);
        }
        catch (IOException e)
        {
            System.err.println("Could not listen to the server port.");
            System.exit (1);
        }

        Socket clientSocket= null;

        try{
            clientSocket= serverSocket.accept();

            new Thread(new Sconsole(clientSocket)).start();
            new Thread(new Slistener(clientSocket)).start();

        }
        catch(Exception e)
        {
            System.err.println("Accept failed");
            System.exit(1);
        }

        stdIn.close();
        clientSocket.close();
        serverSocket.close();
    }
}


/* thread to listen from client and print it at server console */
class Slistener implements Runnable
{
    Socket channel=null;
    public static PrintWriter out = null;
    public static BufferedReader in = null;
    public static String inputL=null;
    public static boolean closed=true;

    public Slistener(Socket Soc)
    {
        this.channel=Soc;

        try
        {
            in=new BufferedReader(new InputStreamReader(channel.getInputStream()));
            //closed=false;

            new Thread(new Slistener(channel));
        }
        catch(IOException e)
        {
            System.out.println("error in making stream from server to client");
        }

    }
    public void run ()
    {
        try
        {
            while((inputL=in.readLine())!= null)
            {
                System.out.println("SERVER:" + inputL);

                if (inputL.equals ("Bye.")) break;
            }

        }
        catch (IOException e)
        {
            System.out.println("Exception thrown at run loop.");
        }
    }
}



/* thread to listen from console at server end and print it at client console */
class Sconsole implements Runnable
{
    Socket channel=null;
    public static PrintWriter out = null;
    public static BufferedReader in = null;
    public static String inputL=null;
    //public static boolean closed=true;

    public Sconsole() {}

    public Sconsole(Socket Soc)
    {
        this.channel=Soc;

        try
        {
            out=new PrintWriter(channel.getOutputStream(), true);
            in=new BufferedReader(new InputStreamReader(System.in));

            //closed=false;

            new Thread(new Sconsole(channel));
        }
        catch(Exception e)
        {
            System.out.println("error in writing to stream from server to client");
        }

    }
    public void run ()
    {
        try
        {
            System.out.println("SERVER:");

            while(true)
            {
                inputL=in.readLine();

                out.println(inputL);

                if (inputL.equals ("End.")) break;
            }
            //closed=true;

        }
        catch (Exception e)
        {
            System.out.println("Exception thrown at run loop.");
        }
    }
}

现在客户端代码:

Cl.java

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

public class Cl extends Thread
{
    public static Socket channel= null;

    public static void main(String args[]) throws IOException
    {
        try{
            channel= new Socket ("localhost", 4321);

            System.out.println("client connected");

            new Thread(new Clistener(channel)).start();
            new Thread(new Cconsole(channel)).start();

        }
        catch (Exception e)
        {
            System.err.println("Unknown Exception");
            System.exit(1);
        }

        channel.close();
    }           
}


  /* thread to listen from server and print it at client console */
class Clistener implements Runnable
{
    Socket channel=null;
    public static PrintWriter out = null;
    public static BufferedReader in = null;
    public static String inputL=null;

    public Clistener() {}

    public Clistener(Socket Soc)
    {
        this.channel=Soc;

        try
        {
            in=new BufferedReader(new InputStreamReader(channel.getInputStream()));

            new Thread(new Clistener(channel));
        }
        catch(IOException e)
        {
            System.out.println("error in making stream from server to client");
        }

    }
    public void run ()
    {
        try
        {
            while(true)
            {
                inputL=in.readLine();

                System.out.println("SERVER:" + inputL);

                if (inputL.equals ("Bye.")) break;
            }



        }
        catch (IOException e)
        {
            System.out.println("Exception thrown at run loop.");
        }
    }
}

  /* thread to listen from client console and print it at server console */
class Cconsole implements Runnable
{
    Socket channel=null;
    public static PrintWriter out = null;
    public static BufferedReader in = null;
    public static String inputL=null;

    public Cconsole(Socket Soc)
    {
        this.channel=Soc;

        try
        {
            out=new PrintWriter(channel.getOutputStream(), true);
            in=new BufferedReader(new InputStreamReader(System.in));

            new Thread(new Cconsole(channel));
        }
        catch(Exception e)
        {
            System.out.println("error in making stream from server to client");
        }
    }

    public void run ()
    {
        try
        {
            while((inputL=in.readLine())!= null )
            {
                System.out.println("CLIENT:");

                out.println(inputL);

                if (inputL.equals ("Bye.")) break;
            }



        }
        catch (Exception e)
        {
            System.out.println("Exception thrown at run loop.");
        }
    }
}

由于每个程序中的两个线程都挂断了,它们分别有什么问题?欢迎任何建议:)

【问题讨论】:

  • 你创建了一些你没有启动的线程(它们不会做任何事情)
  • 刚刚编辑了它。现在分别调用它们并从 main 启动它们。仍然无法正常工作。
  • Clistener 正在从自身创建新的自身实例。我建议改用循环。

标签: java multithreading sockets networking


【解决方案1】:

当我运行您的代码时,它不会挂起:它会因 StackOverflowError 而崩溃。

这是意料之中的:Slistener的构造函数调用Slistener的构造函数,Slistener的构造函数调用Slistener的构造函数,Slistener的构造函数调用Slistener的构造函数,Slistener的构造函数调用Slistener的构造函数,Slistener的构造函数调用Slistener的构造函数Slistener,调用Slistener的构造函数,调用Slistener的构造函数,调用Slistener的构造函数,调用Slistener的构造函数,调用Slistener的构造函数,调用Slistener的构造函数,调用Slistener的构造函数,调用Slistener的构造函数,调用Slistener的构造函数...

Clistener 也是如此。

另外,new Thread(new Sconsole(clientSocket)); 行没有多大意义。构造线程但不启动线程有什么意义。

最后,从构造函数中启动线程是一种非常糟糕的做法。永远不要那样做。

【讨论】:

  • 感谢您的建议。立即通过从 main 而不是在构造函数中调用 run 方法对其进行了编辑。但是服务器 main 仍然抛出一些异常并继续。此异常:**SERVER:线程中的异常“ main" java.lang.NullPointerException at Se.main(Se.java:38) 在运行循环中抛出异常。 ** 和客户端崩溃。我想要的只是创建两个线程来检查两端套接字的输入和输出。对于服务器和客户端。如果不是这样,你能建议我怎么做。如果你可以:)
  • NPE 的堆栈跟踪应该指出异常所在的行。
  • hmm.alright 如果我想为每个服务器和客户端设置两个线程,用于读取和写入,你能告诉我这样做是否正确吗?我是在正确的道路上还是我应该改变什么?任何做和不做的事?我真的很想做这个。如果你能建议我的话,我会很感激的=]
  • 有两个线程而不是一个线程看起来很奇怪。在对话中,通常,A 说话(写)而 B 听(读),然后 B 回答(写)而 A 听(读)。在您的设计中,客户端和服务器同时写入,同时读取。服务器上的每个客户端一个线程是可以的(如果您计划拥有多个客户端)。在客户端,除非您有一些必须保持响应的 GUI,否则我看不出使用线程的意义。
  • 老实说,我知道它看起来很愚蠢。我想我会在将它带到 GUI 之前尝试一下。我知道它很愚蠢。无论如何,非常感谢您的回复 =)
【解决方案2】:

你应该先调用客户端socket输出流的write方法,因为客户端和服务器之间的socket中没有任何东西,但你先写一些东西。

【讨论】:

    猜你喜欢
    • 2010-12-17
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2013-03-27
    • 1970-01-01
    • 2018-07-23
    相关资源
    最近更新 更多