繁体   English   中英

多线程客户端/服务器,套接字异常

[英]Multi-threading client/server, Socket Exception

应该是我无法纠正的简单修复。 我正在返回服务器和客户端之间的总计算量,价格*数量。 但是,我收到了java.net.SocketException: Connection Reset 我已插入ComputerServer类W /类HandleAClientComputerClient类和Computer类。 我欢迎任何帮助。 谢谢!

import java.io.*;
import java.util.*;
import java.net.*;
import java.util.concurrent.Executors;
import java.util.concurrent.ExecutorService;

public class ComputerServer 
{
    public static void main(String args[])
    {
        ServerSocket serverSocket;
        Socket connection;

        ObjectInputStream input;
        ObjectOutputStream output;

        Computer c = null;

        Object obj;

        double totalCharge;

        try
        {
            serverSocket = new ServerSocket(8000);
            System.out.println("Waiting for Client");

            int clientNo = 1;

            ExecutorService threadExecutor = Executors.newCachedThreadPool();

            while(true)//runs indefinitely
            {
                connection = serverSocket.accept();

                input = new ObjectInputStream(connection.getInputStream());
                output = new ObjectOutputStream(connection.getOutputStream());

                obj = input.readObject();

                System.out.println("Object Received from client:\n"+obj);

                if(obj instanceof Computer)
                {
                    totalCharge = ((Computer)obj).getPrice()*((Computer)obj).getQuantity();

                    HandleAClient thread = new HandleAClient(connection, clientNo, totalCharge);

                    threadExecutor.execute(thread);

                    output.writeObject(totalCharge);
                    output.flush();
                }





                clientNo++;
            }

        }
        catch(ClassNotFoundException cnfe)
        {
            cnfe.printStackTrace();
        }
        catch(IOException ioe)
        {
            ioe.printStackTrace();
        }

    }//end of main
}

class HandleAClient implements Runnable
{
    //**SHOULD i do object...
    //Scanner input;
    //Formatter output;
    Object obj;

    ObjectOutputStream output;
    ObjectInputStream input;

    Socket connection;
    ServerSocket serverSocket;

    int clientNo;

    //variables for calculation
    //variables for calculation
    double price;
    double totalCharge;


    public HandleAClient(Socket connection, int clientNo, double totalCharge)
    {
        this.connection = connection;
        this.clientNo = clientNo;
        this.totalCharge = totalCharge;
    }

    public void run()
    {
        //ArrayList<Computer> cList = new ArrayList<Computer>();

        try
        {


            input = new ObjectInputStream(connection.getInputStream());
            output = new ObjectOutputStream(connection.getOutputStream());


            /*while(input.hasNext())
            {
                //variable = input.next....
                //print out calculation
                price = input.nextDouble();
                System.out.println("Price received from client:\t"+clientNo+"is"+price);

                //DO CALCULATION, STORE IT

                for(Computer c: cList)//**TRYING a for loop
                {
                    totalCharge = ((Computer)c).getPrice() * ((Computer)c).getQuantity();

                    output.format("%.2f\n", totalCharge);

                    //output.flush();
                }
            //}*/

            System.out.println("TotalCharge"+totalCharge);
            System.out.println("Thread"+"\t"+clientNo+"\t"+"ended");
        }
        catch(IOException ioe)
        {
            ioe.printStackTrace();
        }
    }
}

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

public class ComputerClient 
{
    public static void main(String args[])
    {
        Socket connection;

        ObjectOutputStream output;
        ObjectInputStream input;

        Object obj;

        Computer c = new Computer("Asus",1189.99,4);

        try
        {
            connection = new Socket("localhost",8000);

            output = new ObjectOutputStream(connection.getOutputStream());
            input = new ObjectInputStream(connection.getInputStream());

            output.writeObject(c);
            output.flush();

            //read back:

            obj=(Object)input.readObject();

            System.out.println(obj.toString());
        }
        catch(ClassNotFoundException cnfe)
        {
            cnfe.printStackTrace();
        }
        catch(IOException ioe)
        {
            ioe.printStackTrace();
        }
    }
}
    import java.io.Serializable;

public class Computer implements Serializable 
{
    private String brand;
    private double price;
    private int quantity;

    public Computer()
    {
        setBrand("");
        setPrice(0.0);
        setQuantity(0);
    }

    public Computer(String b, double p, int q)
    {
        setBrand(b);
        setPrice(p);
        setQuantity(q);
    }

    public String getBrand()
    {
        return brand;
    }

    public double getPrice()
    {
        return price;
    }

    public int getQuantity()
    {
        return quantity;
    }

    public void setBrand(String b)
    {
        brand = b;
    }

    public void setPrice(double p)
    {
        price = p;
    }

    public void setQuantity(int q)
    {
        quantity = q;
    }

    public String toString()
    {
        return("Brand: "+brand+"\t"+"Price: "+price+"\t"+"Quantity: "+quantity);
    }
}

“连接重置”通常意味着您已写入已被同级关闭的连接。 换句话说,应用程序协议错误。 您写的东西是同行没有读过的。 下一个I / O操作或后续的I / O操作(取决于缓冲)将变为“连接重置”。

在这种情况下,服务器正在写入totalCharge并初始化两个ObjectOutputStreams ,这两个对象都将标头写入流中。 客户端仅创建一个ObjectInputStream,该对象读取一个标头,然后读取一个对象,然后关闭连接。 因此,其他标头未写入任何位置,并导致异常。

你做不到 您不能在同一套接字上使用多个ObjectOutputStreams ,至少在没有特别注意的情况下不能这样,这在这里并不明显。 您也不应在accept循环中进行任何I / O操作。 将所有客户端处理移至HandleAClient类,这毕竟是要处理的类,并且在accept循环中不执行任何操作,除非接受连接并为其启动线程。

另外,您的服务器和客户端都没有关闭连接。 服务器只是泄漏套接字,而客户端只是退出。 在客户端的情况下,操作系统会为您关闭它,但这是不明智的做法。 关闭您的连接。 在这种情况下,您应该关闭ObjectOutputStream.

暂无
暂无

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM