【发布时间】:2015-04-19 04:01:57
【问题描述】:
我遇到了一个令人沮丧的问题,我正在尝试为大学考试做准备 - 应该有一堆客户端通过单独服务器上的 tcp 套接字访问资源,这会同步使用权。我有一个基本的入口点类,主要是实例化客户端或服务器,以及一个用于被序列化并通过套接字传递的对象的类:
DataPacket.class 来源:
import java.io.*;
import java.util.Date;
public class DataPacket implements Serializable{
/**
*
*/
private static final long serialVersionUID = 1L;
final public String payload;
final public String creator;
final public Date timestamp;
public DataPacket(String creator, String payload){
this.creator = creator;
this.payload = payload;
this.timestamp = new Date();
}
}
client.class 源在这里:
import java.io.*;
import java.net.*;
import java.util.Random;
public class client extends Thread implements Serializable{
/**
*
*/
private static final long serialVersionUID = 1L;
private String name;
public client(String name){
this.name = name;
}
public void run(){
try {
Socket sock = new Socket(InetAddress.getLocalHost(), 12345);
ObjectInputStream in = new ObjectInputStream(sock.getInputStream());
ObjectOutputStream out = new ObjectOutputStream(sock.getOutputStream());
Random rand = new Random();
// obviously the only reason to have this loop here is to initiate a bunch of access
// requests to the server, but for debugging purposes I've removed the extra cycles
// and stuck to only one;
for(int i=0; i<1; i++){
DataPacket data = new DataPacket(this.name, Integer.toString(rand.nextInt()));
out.writeObject(data);
out.flush();
}
sock.close();
} catch (UnknownHostException e) {
e.printStackTrace();
} catch (IOException e) {
e.printStackTrace();
}
}
}
最后 server.class 源代码在这里:
import java.io.*;
import java.net.*;
public class server extends Thread{
private int port;
private DataPacket dp;
public boolean running=false;
public void updateData(DataPacket dp){
this.dp=dp;
}
public server(int port){
this.port = port;
}
public void run(){
this.running = true;
while (running){
openSocket();
}
}
public void openSocket(){
try {
ServerSocket s = new ServerSocket(this.port, 50, InetAddress.getLocalHost());
while (true){
Socket incomming = s.accept();
ObjectInputStream in = new ObjectInputStream(incomming.getInputStream());
ObjectOutputStream out = new ObjectOutputStream(incomming.getOutputStream());
synchronized (dp){
while ((dp = (DataPacket) in.readObject()) != null) {
System.out.println(dp.creator + "passed a frame @" + dp.timestamp + " :"+dp.payload);
} while (in.readObject() == null){
Thread.sleep(100);
System.out.print(".");
}
}
s.close();
}
} catch (Exception e){
e.printStackTrace();
}
}
}
现在我不知道为什么,但显然客户端也需要定义一个输入流(不做任何从服务器到客户端的对话,但除非我声明,否则它会因一堆拒绝连接异常而爆炸一.为了以防万一,我为了安全起见并在服务器上声明了一个输出。不幸的是,尽管客户端似乎没有通过套接字传递对象,而服务器没有得到它,或者我失败了序列化和反序列化有些悲惨..
虽然我在做这件事,但我希望能得到一些关于服务器上数据访问同步的建议 - 这个“同步 (dp)”会完成这项工作,还是我需要将线程放在客户端手动进入等待队列,并使用 notify() 手动让其中一个客户端传输其序列化数据?
提前致谢! vlex
【问题讨论】:
-
我很惊讶您没有在服务器端看到
NullPointerException on- 您正在null上进行同步。无论如何,请详细说明实际发生的情况。你怎么知道客户端没有发送或服务器没有收到消息?你有没有通过调试器运行过?它表现出什么行为。您遇到了连接错误 - 堆栈跟踪是什么? -
我曾经遇到过 nullpointer 异常,但不记得我是如何修复它们的(过去几天一直在为此苦苦挣扎,而睡眠剥夺对记住我所做的一切并没有多大帮助。 ..) 还没有尝试调试它,因为我不确定我的方法一开始是正确的。只要我有时间修补它,肯定会尝试查看通过套接字传递的内容(如果有的话):) 连接错误要么是因为套接字正在使用,要么是因为连接被拒绝。通过将活动连接数一次减少到 1 个来修复它
-
并为客户端套接字声明一个未使用的输入流。
-
刚刚尝试同时运行 10 个客户端,我的堆栈被填满了:
java.net.BindException: Address already in use: JVM_Bind at java.net.DualStackPlainSocketImpl.bind0(Native Method) at java.net.DualStackPlainSocketImpl.socketBind(Unknown Source) at java.net.AbstractPlainSocketImpl.bind(Unknown Source) at java.net.PlainSocketImpl.bind(Unknown Source) at java.net.ServerSocket.bind(Unknown Source) at java.net.ServerSocket.<init>(Unknown Source) at server.openSocket(server.java:26) at server.run(server.java:20) -
格式无法正常工作 - 抱歉...
标签: java multithreading sockets serialization synchronization