这是一个线程,在服务器上,从客户端发送消息到服务器,服务器这个程序处理

现在出现一个问题,如果我把下面程序while里面循环每次关闭writer流,buffer流则客户端只能发送一次消息,可是我需要的是多次发送消息,如果不关闭writer流,... 现在出现一个问题,如果我把下面程序while里面循环每次关闭writer流,buffer流则客户端只能发送一次消息,可是我需要的是多次发送消息,如果不关闭writer流,buffer流则出现无限循环的状态,程序卡住了一样?求大神解决啊

public static class SocketHandler implements Runnable {
private Socket socket;
public SocketHandler(Socket socket) {
this.socket = socket;
}
@Override
public void run() {
// TODO Auto-generated method stub
try {
InputStreamReader reader = new InputStreamReader(socket.getInputStream());
BufferedReader buffer = new BufferedReader(reader);
PrintWriter writer = new PrintWriter(socket.getOutputStream());
while (true) {
String message = buffer.readLine();
jta.append(message);
User user = new User();
if (message.contains("register")) { // 注册
int begin = message.indexOf("=");
int end = message.indexOf("/>");
user.setName(message.substring(begin + 1, end - 1));
user.setAddress(socket.getInetAddress().toString());
Integer port = new Integer(socket.getLocalPort());
user.setPort(port.toString());
writer.write("<result command=”register” state=”error” message=”” />");
/*if (operateUser.searchUser(user.getName()) == null) {
user.setState(0);
operateUser.insert(user);
writer.write("<result command=”register” state=”ok” />");
} else {*/
//}
}
if (message.contains("login")) { // 登陆
int begin = message.indexOf("=");
int end = message.indexOf("/>");
user.setName(message.substring(begin + 1, end - 1));
user = operateUser.searchUser(user.getName());
if (user == null) {
writer.write("result command=”login” state=”error” message=”” />");
} else {
user.setState(1);
operateUser.modify(user);
writer.write("<result command=” login ” state=”ok” />");
}
System.out.println("dvsdv");
}
if (message.contains("message from")) {
int beginOne = message.indexOf("from=");
int endOne = message.indexOf(" to");
User userOne = operateUser.searchUser(message.substring(beginOne + 1, endOne - 1));
int beginTwo = message.indexOf("=");
int endTwo = message.indexOf(" message");
User userTwo = operateUser.searchUser(message.substring(beginTwo + 1, endTwo - 1));
if (userOne != null && userTwo != null) {
writer.write("<result command=” message ” state=”ok” />");
Socket sentSocket = new Socket(
userTwo.getAddress(),
(int) Integer.parseInt(userTwo.getPort()));
PrintWriter send = new PrintWriter(
sentSocket.getOutputStream());
send.write("");
}
} else {
writer.write("AAAAAAAAAAAAAAa");
}
}
} catch (Exception e) {
e.printStackTrace();
}
}
}
展开
 我来答
jamxval
2012-11-12 · TA获得超过6823个赞
知道大有可为答主
回答量:4308
采纳率:82%
帮助的人:1454万
展开全部
你没明白 Socket 是一个全双工通信,你一句它一句的模式只适合说完了就 close,不适合只 flush 不 close 的情况。当下面情况出现时会死锁:
server: read + write,
client: write + read。因为你没有使用多线程,当 read 没有内容时会阻塞,这就是死锁的关键点。所以只有当对方 write 后 close 了,这边才能从 read 中出来进行 write 过程。

正确的做法是:
1.双线程,一个处理 receive,它读取到内容如果是一个完整的 <request /> 标签就把它解码成一个 request 放入请求消息队列,系统从队列里面拿到请求处理它并把回复放入回复队列。另一个线程处理 send,它从回复队列里面拿到回复消息,发送出去。这两个线程都是会分别阻塞,所以这叫同步式。

2. Java NIO,异步式,当有 read 或 write 消息出现时你的线程处理这个事件读取数据处理,对于 read 事件,读取到后解码成 request 对象放入请求队列;如果是 write 事件发生,则从回复队列拿走消息发送出去。因为 write 事件只要网络正常会连续不停地发生,所以你需要根据回复队列有无消息来判断,没有消息就 Thread.currentThread().yield() 跳过;一个线程可以同时用来处理 read 和 write 事件,但你不应该让这个处理 TCP 的线程来处理 request 本身,因为处理 request 本身是业务内容不是通信过程,处理业务的线程读取请求队列处理完把回复放入回复队列,它和通信过程那个线程是分开的,通过两个队列来交换数据。 这种方案通信过程本身不需要在没有 read 或 write 时阻塞,除非你自己决定当没有 write 消息时阻塞到有 reply 消息时继续。 你在 Sun /Oracle 站点上搜索 Java NIO 样例来实现这个。
推荐律师服务: 若未解决您的问题,请您详细描述您的问题,通过百度律临进行免费专业咨询

为你推荐:

下载百度知道APP,抢鲜体验
使用百度知道APP,立即抢鲜体验。你的手机镜头里或许有别人想知道的答案。
扫描二维码下载
×

类别

我们会通过消息、邮箱等方式尽快将举报结果通知您。

说明

0/200

提交
取消

辅 助

模 式