ServerSocket超时问题

guoqiang139555 2015-04-20 06:02:10
我新建一个ServerSocket,代码如下:
ServerSocket serviceSocket = new ServerSocket(3434);
while (true) {
Socket socket = null;
// 接收客户连接,只要客户进行了连接,就会触发accept();从而建立连接
Socket socket = serviceSocket.accept();
//设置无通讯超时时间,tcp链接超过空闲时间就会抛出异常然后关闭连接
socket.setSoTimeout(60000);
service.execute(new SocketHandler(socket));
}

SocketHandler的代码如下:
BufferedReader br = new BufferedReader(new InputStreamReader(socket.getInputStream()));
logger.info("reader流已经建立。。。。");
StringBuffer socketMsg = new StringBuffer();
String msg = null;
while ((msg = br.readLine()) != null) {
socketMsg.append(msg);
logger.info("服务器端接受信息:" + msg);
if (msg.endsWith("#")) {//遇到#时就结束接收
break;
}
}
logger.info("服务器端接受信息:" + socketMsg.toString());
现在出现一个问题,客户端socket已经连接成功,BufferedReader流也已经新建成功了,但是在br.readLine()的时候抛出一个异常:
java.net.SocketTimeoutException: Read timed out
java.net.SocketTimeoutException: Read timed out
at java.net.SocketInputStream.socketRead0(Native Method)
at java.net.SocketInputStream.read(SocketInputStream.java:152)
at java.net.SocketInputStream.read(SocketInputStream.java:122)
at sun.nio.cs.StreamDecoder.readBytes(StreamDecoder.java:283)
at sun.nio.cs.StreamDecoder.implRead(StreamDecoder.java:325)
at sun.nio.cs.StreamDecoder.read(StreamDecoder.java:177)
at java.io.InputStreamReader.read(InputStreamReader.java:184)
请高手指教,谢谢
...全文
685 26 打赏 收藏 转发到动态 举报
写回复
用AI写文章
26 条回复
切换为时间正序
请发表友善的回复…
发表回复
jae575551342 2015-05-07
  • 打赏
  • 举报
回复
根据你们的响应报文可以看出来是以"#"作为结束符的,而readLine方法需要"\n"作为结束符,所以readLine会一直等待,直到socket连接超时。因此,你们可以尝试通过逐个字符进行读取,如下:

BufferedReader in = new BufferedReader(new InputStreamReader(
						socket.getInputStream()));
				StringBuffer sb = new StringBuffer();
				
				int b ;
				// ASCII中的#为35
				while ((b = in.read()) != 35) {
					sb.append((char)b);
				}
				System.out.println("Server:"+sb.toString());
guoqiang139555 2015-04-23
  • 打赏
  • 举报
回复
引用 24 楼 u011004037 的回复:
额, 我突然想起来, lz的程序应该还没有正式运行吧, 那客户端怎么知道lz的服务器端启动了, 然后主动连接lz的程序呢?
额。。。。就是在现网运行的时候发现这个错误的
youzi05 2015-04-22
  • 打赏
  • 举报
回复
额 lz确定他们正确的发送数据了? 如果方便, 可否提供一下抓的包,还有lz现在的程序版本中的接受数据部分.
guoqiang139555 2015-04-22
  • 打赏
  • 举报
回复
引用 12 楼 u011004037 的回复:
引用
public String readLine() throws IOException 读取一个文本行。通过下列字符之一即可认为某行已终止:换行 ('\n')、回车 ('\r') 或回车后直接跟着换行。 返回: 包含该行内容的字符串,不包含任何行终止符,如果已到达流末尾,则返回 null 抛出: IOException - 如果发生 I/O 错误
这是readLine的文档, 也就是说没有换行之类的字符或者到达末尾, 是不会返回的, 额, 我们需要关注的是换行符什么时候到达, 而不是数据什么时候到达, lz可以看看这个Server/Client通信的典型例子的修改版

import java.net.*;
import java.io.*;

public class SocketClient{
	public static void main( String[] args ) throws Exception{
		Socket client = new Socket( "127.0.0.1", 40000 );
		BufferedReader input = new BufferedReader(new InputStreamReader(System.in));
		PrintStream out = new PrintStream(client.getOutputStream());
		BufferedReader buf = new BufferedReader(new InputStreamReader(client.getInputStream()));

		while(true){
			System.out.println("输入信息>");
			String str = input.readLine();
			out.print(str);
			//System.out.println(buf.readLine());
			if( "exit".equalsIgnoreCase(str) ){
				break;
			}
		}
	}
}

import java.io.*;
import java.net.*;

public class SocketServer{
	public static void main(String[] args) throws Exception{
		ServerSocket server = new ServerSocket(40000);
		Socket client = server.accept();
		PrintStream out = new PrintStream(client.getOutputStream());
		BufferedReader buf = new BufferedReader(new InputStreamReader(client.getInputStream()));
		client.setSoTimeout(60000);

		while(true){
			System.out.println( buf.read() );   // 当用这个读的时候, 没有一点问题, 只不过读到的是ASCII码
			System.out.println( buf.readLine() );  // 用这个读的时候有两种可能, 超时 或者 客户端关闭连接, 抛出异常....
		}
	}
}
郁闷还是不行,我同时用bur.read(),bur.readLine()都试过了,我自己测试的时候怎么都行,但是用他们那个GPS设备发的时候就是只能收到流,流里面是有数据的,但是就是取不到数据,
youzi05 2015-04-22
  • 打赏
  • 举报
回复
额, 我突然想起来, lz的程序应该还没有正式运行吧, 那客户端怎么知道lz的服务器端启动了, 然后主动连接lz的程序呢?
youzi05 2015-04-22
  • 打赏
  • 举报
回复
还是建议lz看看自己的代码, 好多看似不应该的错误都是非常非常非常细小的失误导致的, 而且极难发现, 耐心看看, 调试一下试试吧...
youzi05 2015-04-22
  • 打赏
  • 举报
回复
引用 21 楼 guoqiang139555 的回复:
[quote=引用 20 楼 u011004037 的回复:] 额, lz想想, 多少网站使用的.net, php, jsp, 客户端呢? pc上应该是C, 不照样通信了, 其实网络本来就适应不同架构不同系统之间的互联, 怎么会和语言有关系呢? 不过可能会在一些细节上不一样, 导致不好对接吧, 比如 这个会自动刷新, 那个会积累到一定程度再发,我也不知道, 没学过.net lz最好在过一遍自己的代码, 看看有没有什么细节上有错误,
是的呀,说到底都是底层的网络连接,而且输入流里面已经有数据了,说明他们已经发过来了,但是我就是取不出来。。。[/quote] 刚刚我试了一下, 在linux下, C语言写的客户端和Java写的服务端可以互相通信, 没有一点问题...
guoqiang139555 2015-04-22
  • 打赏
  • 举报
回复
引用 20 楼 u011004037 的回复:
额, lz想想, 多少网站使用的.net, php, jsp, 客户端呢? pc上应该是C, 不照样通信了, 其实网络本来就适应不同架构不同系统之间的互联, 怎么会和语言有关系呢? 不过可能会在一些细节上不一样, 导致不好对接吧, 比如 这个会自动刷新, 那个会积累到一定程度再发,我也不知道, 没学过.net lz最好在过一遍自己的代码, 看看有没有什么细节上有错误,
是的呀,说到底都是底层的网络连接,而且输入流里面已经有数据了,说明他们已经发过来了,但是我就是取不出来。。。
youzi05 2015-04-22
  • 打赏
  • 举报
回复
额, lz想想, 多少网站使用的.net, php, jsp, 客户端呢? pc上应该是C, 不照样通信了, 其实网络本来就适应不同架构不同系统之间的互联, 怎么会和语言有关系呢? 不过可能会在一些细节上不一样, 导致不好对接吧, 比如 这个会自动刷新, 那个会积累到一定程度再发,我也不知道, 没学过.net lz最好在过一遍自己的代码, 看看有没有什么细节上有错误,
guoqiang139555 2015-04-22
  • 打赏
  • 举报
回复
引用 18 楼 u011004037 的回复:
[quote=引用 17 楼 guoqiang139555 的回复:] 弱弱的问下,刚才我问了下他们说客户端是用.net写的,这个有影响吗
额, 这个应该没有影响啊, 网络和使用什么语言又没有关系, 看着发过来的信息没有换行符和回车符(0a/0d),readline收不到还可以理解, 但是read应该能收到啊, 为啥收不到勒?
引用 10 楼 guoqiang139555 的回复:
我用InputStreamReader这个试过,看了下发送时间,是指一分钟以内发过来的
引用 13 楼 guoqiang139555 的回复:
郁闷还是不行,我同时用bur.read(),bur.readLine()都试过了,我自己测试的时候怎么都行,但是用他们那个GPS设备发的时候就是只能收到流,流里面是有数据的,但是就是取不到数据,
难道用InputStreamReader可以收到吗?lz的意思是不是, java程序能收到数据,比如使用InputStreamReader就可以? 只是无法取出?[/quote] 流里面是有数据的,用InputStreamReader和BufferedReader 都取不到数据,然后客户端是用.net写的,这个有影响没
youzi05 2015-04-22
  • 打赏
  • 举报
回复
引用 17 楼 guoqiang139555 的回复:
弱弱的问下,刚才我问了下他们说客户端是用.net写的,这个有影响吗
额, 这个应该没有影响啊, 网络和使用什么语言又没有关系, 看着发过来的信息没有换行符和回车符(0a/0d),readline收不到还可以理解, 但是read应该能收到啊, 为啥收不到勒?
引用 10 楼 guoqiang139555 的回复:
我用InputStreamReader这个试过,看了下发送时间,是指一分钟以内发过来的
引用 13 楼 guoqiang139555 的回复:
郁闷还是不行,我同时用bur.read(),bur.readLine()都试过了,我自己测试的时候怎么都行,但是用他们那个GPS设备发的时候就是只能收到流,流里面是有数据的,但是就是取不到数据,
难道用InputStreamReader可以收到吗?lz的意思是不是, java程序能收到数据,比如使用InputStreamReader就可以? 只是无法取出?
guoqiang139555 2015-04-22
  • 打赏
  • 举报
回复
弱弱的问下,刚才我问了下他们说客户端是用.net写的,这个有影响吗
guoqiang139555 2015-04-22
  • 打赏
  • 举报
回复
我截图里是三次握手时间和第三张图是流里面发送的内容
guoqiang139555 2015-04-22
  • 打赏
  • 举报
回复
引用 14 楼 u011004037 的回复:
额 lz确定他们正确的发送数据了? 如果方便, 可否提供一下抓的包,还有lz现在的程序版本中的接受数据部分.




代码就是
public class SocketServer{
public static void main(String[] args) throws Exception{
ServerSocket server = new ServerSocket(40000);
Socket client = server.accept();
PrintStream out = new PrintStream(client.getOutputStream());
BufferedReader buf = new BufferedReader(new InputStreamReader(client.getInputStream()));
client.setSoTimeout(60000);

while(true){
System.out.println( buf.read() ); // 当用这个读的时候, 没有一点问题, 只不过读到的是ASCII码
System.out.println( buf.readLine() ); // 用这个读的时候有两种可能, 超时 或者 客户端关闭连接, 抛出异常....
}
}
}
这样的,这两种方式我都试过了
guoqiang139555 2015-04-21
  • 打赏
  • 举报
回复
引用 1 楼 wangxf_8341 的回复:
客户端有没有对输出流进行flush
我问了下,他们是有flush的,而且我们这个抓了下包,发现是可以收到他们发送的消息的,这是为什么那
guoqiang139555 2015-04-21
  • 打赏
  • 举报
回复
@wangxf_8341 :客户端有没有对输出流进行flush 这个应该是有道理的,我问下
guoqiang139555 2015-04-21
  • 打赏
  • 举报
回复
引用 2 楼 u011004037 的回复:
额,不知道你客户端的代码, 超时是不是手工输入太慢了, 超时还可能是另一个原因,就是接收的"#"带有回车/换行,所以该退出时却没有退出,还在接收,然后就超时了, lz可以试试把判断条件改为

if (msg.trim().endsWith("#")) {//遇到#时就结束接收  
          break;  
 } 
客户端是一个车载系统,根据他们说,他们是发送到附近的基站,然后通过基站发送数据的,应该和输入快慢没什么关系,还有我自己写了socket测试,因为有(msg = br.readLine()) != null 这个判断条件为前提,所以endsWith(“#”)这个应该没关系的
youzi05 2015-04-21
  • 打赏
  • 举报
回复
引用
public String readLine() throws IOException 读取一个文本行。通过下列字符之一即可认为某行已终止:换行 ('\n')、回车 ('\r') 或回车后直接跟着换行。 返回: 包含该行内容的字符串,不包含任何行终止符,如果已到达流末尾,则返回 null 抛出: IOException - 如果发生 I/O 错误
这是readLine的文档, 也就是说没有换行之类的字符或者到达末尾, 是不会返回的, 额, 我们需要关注的是换行符什么时候到达, 而不是数据什么时候到达, lz可以看看这个Server/Client通信的典型例子的修改版

import java.net.*;
import java.io.*;

public class SocketClient{
	public static void main( String[] args ) throws Exception{
		Socket client = new Socket( "127.0.0.1", 40000 );
		BufferedReader input = new BufferedReader(new InputStreamReader(System.in));
		PrintStream out = new PrintStream(client.getOutputStream());
		BufferedReader buf = new BufferedReader(new InputStreamReader(client.getInputStream()));

		while(true){
			System.out.println("输入信息>");
			String str = input.readLine();
			out.print(str);
			//System.out.println(buf.readLine());
			if( "exit".equalsIgnoreCase(str) ){
				break;
			}
		}
	}
}

import java.io.*;
import java.net.*;

public class SocketServer{
	public static void main(String[] args) throws Exception{
		ServerSocket server = new ServerSocket(40000);
		Socket client = server.accept();
		PrintStream out = new PrintStream(client.getOutputStream());
		BufferedReader buf = new BufferedReader(new InputStreamReader(client.getInputStream()));
		client.setSoTimeout(60000);

		while(true){
			System.out.println( buf.read() );   // 当用这个读的时候, 没有一点问题, 只不过读到的是ASCII码
			System.out.println( buf.readLine() );  // 用这个读的时候有两种可能, 超时 或者 客户端关闭连接, 抛出异常....
		}
	}
}
cqnaqjy 2015-04-21
  • 打赏
  • 举报
回复
楼主 你确定你接收到数据了 不是连接就行了 你看是否接收到数据 BufferedReader br = new BufferedReader(new InputStreamReader(socket.getInputStream()));
guoqiang139555 2015-04-21
  • 打赏
  • 举报
回复
引用 9 楼 u011004037 的回复:
也就是说,一次都没有读进来? 那要不试试用BufferedReader的这个方法读, 一次10个字符, public int read(char[] cbuf, int off, int len) 另外, lz不是抓包了吗? 看看他们连接的时间, 还有他们发送一个回车符或者结束连接的时间, 之间的差值是不是大于1分钟
我用InputStreamReader这个试过,看了下发送时间,是指一分钟以内发过来的
加载更多回复(6)

67,512

社区成员

发帖
与我相关
我的任务
社区描述
J2EE只是Java企业应用。我们需要一个跨J2SE/WEB/EJB的微容器,保护我们的业务核心组件(中间件),以延续它的生命力,而不是依赖J2SE/J2EE版本。
社区管理员
  • Java EE
加入社区
  • 近7日
  • 近30日
  • 至今
社区公告
暂无公告

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