[英]Multi-threading client/server, Socket Exception
应该是我无法纠正的简单修复。 我正在返回服务器和客户端之间的总计算量,价格*数量。 但是,我收到了java.net.SocketException: Connection Reset
。 我已插入ComputerServer
类W /类HandleAClient
, ComputerClient
类和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.