socket 服务端 长连接问题

码农东哥 2015-02-03 03:04:40
各位大神,我问个问题:我使用Socket写了一个服务器,别人访问我的时候,他程序启动之后,发送数据可以成功返回,然后再发送就失败,再次发送又成功了,以此循环下去,就是从第二次开始,每次发送,第一次是打开连接,第二次才是发送数据。
public class EchoThread extends Thread {

protected PrintStream out;
protected String message;
protected Socket clientSocket;

public EchoThread(Socket clientSocket) {
super();
try {
// 接受数据,但不允许有中文,因为会乱码
DataInputStream in = new DataInputStream(
clientSocket.getInputStream());
byte[] buffer = new byte[10000]; // 缓冲区的大小
in.read(buffer); // 处理接收到的报文,转换成字符串
/**
* C++传递过来的中文字,需要转化一下。C++默认使用GBK。
* GB2312是GBK的子集,只有简体中文。因为数据库用GB2312,所以这里直接转为GB2312
* */
message = new String(buffer, "GB2312").trim();
this.clientSocket = clientSocket;
// 获得输出输出流
out = new PrintStream(clientSocket.getOutputStream());
} catch (IOException ex) {
Logger.getLogger(EchoServerThread.class.getName()).log(
Level.SEVERE, null, ex);
}finally{
try {
if(clientSocket !=null)
clientSocket.close();
} catch (IOException ex1) {
Logger.getLogger(EchoServerThread.class.getName()).log(
Level.SEVERE, null, ex1);
}
}
}

public void run() {
try {
/**
* 这里需要使用底层的byte方法来传递。因为即使直接写字符串,到底层还是调用了传递byte的方法。
* 这里涉及到编码问题。C++默认使用GBK,而GB2312是GBK的子集。
*/
byte[] responseBuffer = new ClientRequestHandler(message)
.response().getBytes("GB2312");
out.write(responseBuffer, 0, responseBuffer.length);
// String test = new ClientRequestHandler(message).response();
// out.print(test);//直接UTF8输出,最终底层每个中文用3个字节传输
// out.print(new
// String(test.getBytes(),"GBK"));//转GBK失败,实际每个中文字用了4到5个字节传递
// out.print(new
// String(test.getBytes("GBK"),"GBK"));//转GBK,但底层还是要拆成字节数组,当然最终还是跟UTF8一样
// sleep(1000);
} catch (Exception ex) {
Logger.getLogger(EchoThread.class.getName()).log(Level.SEVERE,
null, ex);
}
try {
clientSocket.close();
} catch (IOException ex) {
Logger.getLogger(EchoThread.class.getName()).log(Level.SEVERE,
null, ex);
}
}

public String getMessage() {
return message;
}

/**
* 获取输出流
*
* @return
*/
public PrintStream getOutputStream() {
return out;
}
}
public class EchoServerThread {
// 服务端侦听的Socket
ServerSocket serverSkt = null;
// 构造方法
public EchoServerThread(int port) {
System.out.println("服务器代理正在监听,端口:" + port);
try {
// 创建监听socket
serverSkt = new ServerSocket(port);
} catch (IOException ex) {
Logger.getLogger(EchoServerThread.class.getName()).log(
Level.SEVERE, null, ex);
}

while (true) {
try {
// 接收连接请求
Socket clientSocket = serverSkt.accept();
EchoThread et = new EchoThread(clientSocket);
// et.setDaemon(true);
et.start();
} catch (IOException e) {
System.out.println("无法接受当前客户连接请求!");
break;
}
}
}
}

和这个问题是一模一样的:http://bbs.csdn.net/topics/330162464
...全文
162 2 打赏 收藏 转发到动态 举报
写回复
用AI写文章
2 条回复
切换为时间正序
请发表友善的回复…
发表回复
普凡 2015-02-04
  • 打赏
  • 举报
回复
楼上说的对,具体代码(示意代码)可能是这样:

while (running) {
				try {
					Socket socket = socketServer.accept();
					BufferedReader reader = new BufferedReader(new InputStreamReader(socket.getInputStream(),"UTF-8"));
					String cmd = reader.readLine();					

						CmdCenter cc = new CmdCenter(socket,reader,cmd);
						cc.setDaemon(false);
						cc.start();

				} catch (Exception e) {
					logger.error(e.getMessage());
				}
			}
rumlee 2015-02-03
  • 打赏
  • 举报
回复
你应该在服务端的处理线程中,通过while(true)去接收消息,你直接在线程的构造函数中接收了消息(实际上这时候还是在主线程运行的),并且立即将socket关闭了,所以你这里开启线程一点意义都没有。socket都关闭了,下次再发当然就不行了。 至于你说的通一次断一次,依次循环,那应该是你的客户端对断了之后做了处理,就是接着下一次再重新连接。 关键原因就是你的服务端收了一条消息之后就立即关闭了。

62,615

社区成员

发帖
与我相关
我的任务
社区描述
Java 2 Standard Edition
社区管理员
  • Java SE
加入社区
  • 近7日
  • 近30日
  • 至今
社区公告
暂无公告

试试用AI创作助手写篇文章吧