非常神奇的Java Socket问题,请高手帮忙分析一下问题的原因。

coolhty 2012-03-22 10:08:59
一模一样的一段socket代码,如果放在struts的action里面,就会出现连接不上的情况,但是运气好的话,有时候还是能连接上,查了目标服务器,没有接收到socket连接。本地服务器有网络连接,运行lsof -i:端口,显示的是:本地IP>>目标服务器IP:streettalk FIN_WAIT1

如果我把代码单独放在一个类里面,然后编译出来,用终端运行,每次都可以成功。
接着用c写了同样的一样代码,连接也是没问题的。

还有个问题是,我连接目标服务器的任何端口,即使目标端口没有开,socket的isConnected是true,isClosed显示false。
只有在read那里才会阻塞10秒,如果去掉read部分,异常都不会报。

端口没开应该连接失败才对呀..

本地系统是 Centos 6.1,目标服务器是windows,程序是MFC

代码如下:

public static void main(String[] args) throws IOException, InterruptedException {
Socket socket = new Socket();
try {
socket.setSoLinger(true, 60);
socket.setTrafficClass(0x04|0x10);
socket.setPerformancePreferences(2, 1, 3);
socket.setTcpNoDelay(true);
socket.setReceiveBufferSize(1);
socket.setSoTimeout(10000);
socket.connect(new InetSocketAddress("目标服务器IP", 65522));
socket.getOutputStream().write("GeHO04fGZx9owa/tTCTBJlCQFbZWGqClSzFNagF7XkHJjxcniWXjQn2Fmb6S9H+LV2KBoRwLfPQfoay20cJxjtZyisPo2yFb64qcLzgVgs3fq2F88C87tdlK6Oy6/iEE".getBytes());

System.out.println("is connect:"+socket.isConnected());
System.out.println("is close:"+socket.isClosed());

int flag = 0;
InputStream is = socket.getInputStream();
byte[] b = new byte[2];
if(-1 != is.read(b,0,1)) {
if(Character.isDigit(b[0])) {
flag = Character.getNumericValue(b[0]);
}
}

System.out.println(flag);

socket.close();
} catch (SocketException e) {
e.printStackTrace();
} catch (IOException e) {
e.printStackTrace();
}
}
...全文
190 点赞 收藏 12
写回复
12 条回复
既然是非阻塞的,那说明socket连接成功了。
我觉得这跟系统关系应该不大,和服务端的消息处理方式可能有关。只是不知道一些细节。
回复 点赞
coolhty 2012年03月24日
[Quote=引用 10 楼 dracularking 的回复:]

*FIN_WAIT1*

The application on local machine has closed the connection. Indication of this has been sent to the remote machine.

我覺得你可以先確認下爲什麽服務端端口關閉了還可以連接這個事
或者這個socket connect是non-blo……
[/Quote]

我没有用非阻塞。

现在问题是解决了,但是解决的方法很奇怪。。Thread.sleep(100);既然是这样解决的,因为这个发送有两种数据,一种数据比较大,一种数据很小,只有不到一百的字符。。数据大的每次都可以成功,数据小的经常不成功,但还是有成功的几率,我就硬着头皮想,可能是数据太小了,发得太快了,让线程暂停100毫秒,没想到这样就没问题了。
反正100毫秒客户也感觉不出来,现在也没更好的办法去解决,只能这样了。。以后再看能不能发现问题。。

估计是与系统有关,因为在windows上面跑的时候没点问题。
回复 点赞
*FIN_WAIT1*

The application on local machine has closed the connection. Indication of this has been sent to the remote machine.

我覺得你可以先確認下爲什麽服務端端口關閉了還可以連接這個事
或者這個socket connect是non-blocking mode或者是你判斷錯了(服務端如果完全不開呢)
回复 点赞
coolhty 2012年03月22日
又发现,如果在Servlet里面,将IP,端口,传输的数据,给另外一个类去连接的话,同样失败,成功的机率有,但是非常渺小。。

不存在线程同步问题,因为那个传输类每次使用的时候都是new的
回复 点赞
coolhty 2012年03月22日
又有新发现,在Servlet里面同样的Socket代码,也没问题。
回复 点赞
xiaolong82008 2012年03月22日
Socket Socket Socket没有实践
回复 点赞
coolhty 2012年03月22日
请高手帮忙分析一下,谢谢了。
回复 点赞
coolhty 2012年03月22日
将socket.setSoLinger(true, 60);关闭可以稍微解决问题。。。

这到底是为什么
回复 点赞
coolhty 2012年03月22日
[Quote=引用 7 楼 dracularking 的回复:]

連接不成功的時候應該有異常吧,異常是什麽呢
[/Quote]

没连接不成功的异常,只有在读取数据的时候抛出异常,读取超时。

打开连接后状态是FIN_WAIT1,有时候又可以成功,但是基本上都是失败。

还有一些很奇怪的问题,上面的几个跟帖说了。。。头疼,根本没地方去找问题。。

说是系统问题吧,单独写的java程序可以很顺利的连接;直接把socket的内容放到一个servlet里面用get方法去请求,也没问题。
回复 点赞
連接不成功的時候應該有異常吧,異常是什麽呢
回复 点赞
coolhty 2012年03月22日
继续等待高手指点。。
回复 点赞
发动态
发帖子
Java EE
创建于2007-09-28

3.7w+

社区成员

22.5w+

社区内容

J2EE只是Java企业应用。我们需要一个跨J2SE/WEB/EJB的微容器,保护我们的业务核心组件(中间件),以延续它的生命力,而不是依赖J2SE/J2EE版本。
社区公告
暂无公告