针对套接字输入和输出的单独线程的建议

时间:2011-12-03 10:40:32

标签: java multithreading sockets networking

我正在尝试在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.");
        }
    }
}

每个程序中的两个线程分别有什么问题,因为它们挂了?任何建议都会受到欢迎:)

2 个答案:

答案 0 :(得分:3)

当我运行你的代码时,它不会挂起:它与StackOverflowError崩溃。

这是预期的:Slistener的构造函数调用Slistener的构造函数,该构造函数调用Slistener的构造函数,该构造函数调用Slistener的构造函数,该构造函数调用Slistener的构造函数,该构造函数调用Slistener的构造函数,该构造函数调用构造函数。 Slistener,调用Slistener的构造函数,调用Slistener的构造函数,调用Slistener的构造函数,调用Slistener的构造函数,调用Slistener的构造函数,调用Slistener的构造函数,调用Slistener的构造函数,调用Slistener的构造函数。 ,它调用Slistener的构造函数,它调用Slistener的构造函数......

Clistener也一样。

此外,行new Thread(new Sconsole(clientSocket));没有多大意义。构建线程但没有启动它的重点是什么。

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

答案 1 :(得分:1)

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