java中如何关闭套接字_无法关闭它,无法通过Java套接字发送消息

我正在编写一个大型Java应用程序的服务器部分,用于使用Java套接字通过TCP / IP与客户端进行通信。客户端(用PHP编写)连接到服务器,以XML格式发送查询,然后服务器发回响应。查询响应可以在单个连接中重复多次。

服务器端很简单。它应该允许多个客户端连接,所以有一个线程监听并为每个接受的连接产生一个会话。会话包含一个对象,该对象包含两个用于传输和接收的LinkedBlockingQueues,两个用于使用这些队列传输和接收消息的线程以及一个处理线程。

问题是任何消息只有在套接字关闭后才被实际传输。响应消息没有问题地进入消息队列和PrintStream.println()方法,但wireshark仅在客户端关闭连接时报告传输。使用启用自动刷新或使用flush()创建PrintStream不起作用。关闭服务器端的套接字也不起作用,服务器仍然运行并接收消息。

当前在服务器端接收查询的客户端工作正常,在本地Linux虚拟机中echo -e "test" | socat - TCP4:192.168.37.1:1337也是如此,但是当我telnet到服务器并尝试发送某些内容时,服务器在我关闭之前不会收到任何内容远程登录客户端也会遇到与上述相同的问题。

相关的服务器代码(整个应用程序太大而无法粘贴所有内容,我正在处理很多其他人的代码):

package Logic.XMLInterfaceForClient;

import java.io.BufferedReader;

import java.io.IOException;

import java.io.InputStreamReader;

import java.io.PrintStream;

import java.net.Socket;

import java.util.HashSet;

import java.util.concurrent.LinkedBlockingQueue;

import Data.Config;

import Logic.Log;

public class ClientSession {

/**

* @author McMonster

*

*/

public class MessageTransmitter extends Thread {

private final Socket socket;

private final ClientSession parent;

private PrintStream out;

/**

* @param socket

* @param parent

*/

public MessageTransmitter(Socket socket, ClientSession parent) {

this.socket = socket;

this.parent = parent;

}

/*

* (non-Javadoc)

*

* @see java.lang.Runnable#run()

*/

@Override

public void run() {

try {

out = new PrintStream(socket.getOutputStream(), true);

while (!socket.isClosed()) {

try {

String msg = parent.transmit.take();

// System.out.println(msg);

out.println(msg);

out.flush();

}

catch(InterruptedException e) {

// INFO: purposefully left empty to suppress spurious

// wakeups

}

}

}

catch(IOException e) {

parent.fail(e);

}

}

}

/**

* @author McMonster

*

*/

public class MessageReceiver extends Thread {

private final Socket socket;

private final ClientSession parent;

private BufferedReader in;

/**

* @param socket

* @param parent

*/

public MessageReceiver(Socket socket, ClientSession parent) {

this.socket = socket;

this.parent = parent;

}

/*

* (non-Javadoc)

*

* @see java.lang.Runnable#run()

*/

@Override

public void run() {

try {

in = new BufferedReader(new InputStreamReader(socket.getInputStream()));

while (!socket.isClosed()) {

String message = "";

String line;

while ((line = in.readLine()) != null) {

message = message + line + "\n";

}

if(message != "") {

parent.receive.offer(message.toString());

}

}

}

catch(IOException e) {

parent.fail(e);

}

}

}

public final LinkedBlockingQueue transmit = new LinkedBlockingQueue<>();

public final LinkedBlockingQueue receive = new LinkedBlockingQueue<>();

private final XMLQueryHandler xqh;

private final Socket socket;

private String user = null;

private HashSet privileges = null;

/**

* @param socket

* @param config

* @throws IOException

* @throws IllegalArgumentException

*/

public ClientSession(Socket socket, Config config)

throws IOException,

IllegalArgumentException {

// to avoid client session without the client

if(socket == null) throw new IllegalArgumentException("Socket can't be null.");

this.socket = socket;

// we do not need to keep track of the two following threads since I/O

// operations are currently blocking, closing the sockets will cause

// them to shut down

new MessageReceiver(socket, this).start();

new MessageTransmitter(socket, this).start();

xqh = new XMLQueryHandler(config, this);

xqh.start();

}

public void triggerTopologyRefresh() {

xqh.setRefresh(true);

}

public void closeSession() {

try {

xqh.setFinished(true);

socket.close();

}

catch(IOException e) {

e.printStackTrace();

Log.write(e.getMessage());

}

}

/**

* Used for reporting failures in any of the session processing threads.

* Handles logging of what happened and shuts down all session threads.

*

* @param t

* cause of the failure

*/

synchronized void fail(Throwable t) {

t.printStackTrace();

Log.write(t.getMessage());

closeSession();

}

synchronized boolean userLogin(String login, HashSet privileges) {

boolean success = false;

if(!privileges.isEmpty()) {

user = login;

this.privileges = privileges;

success = true;

}

return success;

}

public synchronized boolean isLoggedIn() {

return user != null;

}

/**

* @return the privileges

*/

public HashSet getPrivileges() {

return privileges;

}

}

  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值