我新建一个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 socket Msg = 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)
请高手指教,谢谢
客户端有没有对输出流进行flush
额,不知道你客户端的代码, 超时是不是手工输入太慢了,
超时还可能是另一个原因,就是接收的”#”带有回车/换行,所以该退出时却没有退出,还在接收,然后就超时了, lz可以试试把判断条件改为
if (msg.trim().endsWith("#")) {//遇到#时就结束接收
break;
}
引用 2 楼 u011004037 的回复:
额,不知道你客户端的代码, 超时是不是手工输入太慢了,
超时还可能是另一个原因,就是接收的”#”带有回车/换行,所以该退出时却没有退出,还在接收,然后就超时了, lz可以试试把判断条件改为
if (msg.trim().endsWith("#")) {//遇到#时就结束接收
break;
}
客户端是一个车载系统,根据他们说,他们是发送到附近的基站,然后通过基站发送数据的,应该和输入快慢没什么关系,还有我自己写了socket测试,因为有(msg = br.readLine()) != null 这个判断条件为前提,所以endsWith(“#”)这个应该没关系的
@wangxf_8341 :客户端有没有对输出流进行flush 这个应该是有道理的,我问下
引用 1 楼 wangxf_8341 的回复:
客户端有没有对输出流进行flush
我问了下,他们是有flush的,而且我们这个抓了下包,发现是可以收到他们发送的消息的,这是为什么那
引用 5 楼 guoqiang139555 的回复:
Quote: 引用 1 楼 wangxf_8341 的回复:
客户端有没有对输出流进行flush
我问了下,他们是有flush的,而且我们这个抓了下包,发现是可以收到他们发送的消息的,这是为什么那
lz可以打印一下啊, 试试这个代码, 然后把日志发出来呗
while ((msg = br.readLine()) != null) {
socketMsg.append(msg);
logger.info("服务器端接受信息: [" + msg + "]");
if (msg.endsWith("#")) {//遇到#时就结束接收
logger.info( "退出" );
break;
}
}
引用 6 楼 u011004037 的回复:
Quote: 引用 5 楼 guoqiang139555 的回复:
Quote: 引用 1 楼 wangxf_8341 的回复:
客户端有没有对输出流进行flush
我问了下,他们是有flush的,而且我们这个抓了下包,发现是可以收到他们发送的消息的,这是为什么那
lz可以打印一下啊, 试试这个代码, 然后把日志发出来呗
while ((msg = br.readLine()) != null) {
socketMsg.append(msg);
logger.info("服务器端接受信息: [" + msg + "]");
if (msg.endsWith("#")) {//遇到#时就结束接收
logger.info( "退出" );
break;
}
}
没用的,在执行while ((msg = br.readLine()) != null) { 这句话的时候报的错,所以你们的日志不会打印出来的
引用 6 楼 u011004037 的回复:
Quote: 引用 5 楼 guoqiang139555 的回复:
Quote: 引用 1 楼 wangxf_8341 的回复:
客户端有没有对输出流进行flush
我问了下,他们是有flush的,而且我们这个抓了下包,发现是可以收到他们发送的消息的,这是为什么那
lz可以打印一下啊, 试试这个代码, 然后把日志发出来呗
while ((msg = br.readLine()) != null) {
socketMsg.append(msg);
logger.info("服务器端接受信息: [" + msg + "]");
if (msg.endsWith("#")) {//遇到#时就结束接收
logger.info( "退出" );
break;
}
}
没用的,在执行while ((msg = br.readLine()) != null) { 这句话的时候报的错,所以里面的日志不会打印出来的
也就是说,一次都没有读进来?
那要不试试用BufferedReader的这个方法读, 一次10个字符,
public int read(char[] cbuf, int off, int len)
另外, lz不是抓包了吗? 看看他们连接的时间, 还有他们发送一个回车符 或者结束连接的时间, 之间的差值是不是大于1分钟
引用 9 楼 u011004037 的回复:
也就是说,一次都没有读进来?
那要不试试用BufferedReader的这个方法读, 一次10个字符,
public int read(char[] cbuf, int off, int len)
另外, lz不是抓包了吗? 看看他们连接的时间, 还有他们发送一个回车符 或者结束连接的时间, 之间的差值是不是大于1分钟
我用InputStreamReader这个试过,看了下发送时间,是指一分钟以内发过来的
楼主 你确定你接收到数据了 不是连接就行了 你看是否接收到数据
BufferedReader br = new BufferedReader(new InputStreamReader(socket.getInputStream()));
引用
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() ); // 用这个读的时候有两种可能, 超时 或者 客户端关闭连接, 抛出异常....
}
}
}
引用 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设备发的时候就是只能收到流,流里面是有数据的,但是就是取不到数据,
额 lz确定他们正确的发送数据了? 如果方便, 可否提供一下抓的包,还有lz现在的程序版本中的接受数据部分.
引用 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() ); // 用这个读的时候有两种可能, 超时 或者 客户端关闭连接, 抛出异常….
}
}
}
这样的,这两种方式我都试过了
我截图里是三次握手时间和第三张图是流里面发送的内容
弱弱的问下,刚才我问了下他们说客户端是用.net写的,这个有影响吗
引用 17 楼 guoqiang139555 的回复:
弱弱的问下,刚才我问了下他们说客户端是用.net写的,这个有影响吗
额, 这个应该没有影响啊, 网络和使用什么语言又没有关系, 看着发过来的信息没有换行符和回车符(0a/0d),readline收不到还可以理解, 但是read应该能收到啊, 为啥收不到勒?
引用 10 楼 guoqiang139555 的回复:
我用InputStreamReader这个试过,看了下发送时间,是指一分钟以内发过来的
引用 13 楼 guoqiang139555 的回复:
郁闷还是不行,我同时用bur.read(),bur.readLine()都试过了,我自己测试的时候怎么都行,但是用他们那个GPS设备发的时候就是只能收到流,流里面是有数据的,但是就是取不到数据,
难道用InputStreamReader可以收到吗?lz的意思是不是, java程序能收到数据,比如使用InputStreamReader就可以? 只是无法取出?
引用 18 楼 u011004037 的回复:
Quote: 引用 17 楼 guoqiang139555 的回复:
弱弱的问下,刚才我问了下他们说客户端是用.net写的,这个有影响吗
额, 这个应该没有影响啊, 网络和使用什么语言又没有关系, 看着发过来的信息没有换行符和回车符(0a/0d),readline收不到还可以理解, 但是read应该能收到啊, 为啥收不到勒?
引用 10 楼 guoqiang139555 的回复:
我用InputStreamReader这个试过,看了下发送时间,是指一分钟以内发过来的
引用 13 楼 guoqiang139555 的回复:
郁闷还是不行,我同时用bur.read(),bur.readLine()都试过了,我自己测试的时候怎么都行,但是用他们那个GPS设备发的时候就是只能收到流,流里面是有数据的,但是就是取不到数据,
难道用InputStreamReader可以收到吗?lz的意思是不是, java程序能收到数据,比如使用InputStreamReader就可以? 只是无法取出?
流里面是有数据的,用InputStreamReader和BufferedReader 都取不到数据,然后客户端是用.net写的,这个有影响没
额, lz想想, 多少网站使用的.net, php, jsp, 客户端呢? pc上应该是C, 不照样通信了, 其实网络本来就适应不同架构不同系统之间的互联, 怎么会和语言有关系呢?
不过可能会在一些细节上不一样, 导致不好对接吧, 比如 这个会自动刷新, 那个会积累到一定程度再发,我也不知道, 没学过.net
lz最好在过一遍自己的代码, 看看有没有什么细节上有错误,
引用 20 楼 u011004037 的回复:
额, lz想想, 多少网站使用的.net, php, jsp, 客户端呢? pc上应该是C, 不照样通信了, 其实网络本来就适应不同架构不同系统之间的互联, 怎么会和语言有关系呢?
不过可能会在一些细节上不一样, 导致不好对接吧, 比如 这个会自动刷新, 那个会积累到一定程度再发,我也不知道, 没学过.net
lz最好在过一遍自己的代码, 看看有没有什么细节上有错误,
是的呀,说到底都是底层的网络连接,而且输入流里面已经有数据了,说明他们已经发过来了,但是我就是取不出来。。。
引用 21 楼 guoqiang139555 的回复:
Quote: 引用 20 楼 u011004037 的回复:
额, lz想想, 多少网站使用的.net, php, jsp, 客户端呢? pc上应该是C, 不照样通信了, 其实网络本来就适应不同架构不同系统之间的互联, 怎么会和语言有关系呢?
不过可能会在一些细节上不一样, 导致不好对接吧, 比如 这个会自动刷新, 那个会积累到一定程度再发,我也不知道, 没学过.net
lz最好在过一遍自己的代码, 看看有没有什么细节上有错误,
是的呀,说到底都是底层的网络连接,而且输入流里面已经有数据了,说明他们已经发过来了,但是我就是取不出来。。。
刚刚我试了一下, 在linux下, C语言写的客户端和Java写的服务端可以互相通信, 没有一点问题…
还是建议lz看看自己的代码, 好多看似不应该的错误都是非常非常非常细小的失误导致的, 而且极难发现, 耐心看看, 调试一下试试吧…
额, 我突然想起来, lz的程序应该还没有正式运行吧, 那客户端怎么知道lz的服务器端启动了, 然后主动连接lz的程序呢?
引用 24 楼 u011004037 的回复:
额, 我突然想起来, lz的程序应该还没有正式运行吧, 那客户端怎么知道lz的服务器端启动了, 然后主动连接lz的程序呢?
额。。。。就是在现网运行的时候发现这个错误的
40分
根据你们的响应报文可以看出来是以”#”作为结束符的,而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());