用两个数据输入流接收同一个socket客户端接收数据么

2012年9月 Windows专区大版内专家分月排行榜第一2012年9月 C/C++大版内专家分月排行榜第一2012年8月 Windows专区大版内专家分月排行榜第一
2012年9月 其他开发语言大版内专家分月排行榜第二2012年8月 VC/MFC大版内专家分月排行榜第二2012年8月 其他开发语言大版内专家分月排行榜第二
2013年9月 VC/MFC大版内专家分月排行榜第一2013年8月 VC/MFC大版内专家分月排行榜第一
2012年2月 VC/MFC大版内专家分月排行榜第二2011年3月 VC/MFC大版内专家分月排行榜第二2011年2月 VC/MFC大版内专家分月排行榜第二
2013年9月 VC/MFC大版内专家分月排行榜第一2013年8月 VC/MFC大版内专家分月排行榜第一
2012年2月 VC/MFC大版内专家分月排行榜第二2011年3月 VC/MFC大版内专家分月排行榜第二2011年2月 VC/MFC大版内专家分月排行榜第二
2012年9月 Windows专区大版内专家分月排行榜第一2012年9月 C/C++大版内专家分月排行榜第一2012年8月 Windows专区大版内专家分月排行榜第一
2012年9月 其他开发语言大版内专家分月排行榜第二2012年8月 VC/MFC大版内专家分月排行榜第二2012年8月 其他开发语言大版内专家分月排行榜第二
本帖子已过去太久远了,不再提供回复功能。14:53 提问
socket循环发送请求并读取响应时,循环到第二次之后就读不到响应内容
问题描述:
业务需求是有一个报文数组,我遍历该数组,每取到一个报文串,便通过socket发送至服务端处理,然后读取服务端响应的报文。但是经过反复测试,每次循环第一次的流程是正常的,但是循环到第二次之后,却读不到响应的报文(内容为空)。求各路神仙大虾帮我看看(PS:我看过网上很多的帖子,有的人说socket输入流就像一个一次性的杯子,只能使用一次。但是按这样的话,我岂不是每次发送都需要建立socket连接?这样太消耗资源了吧)。
这是我的业务逻辑代码
public void sendReq(String[] RequestXml) throws Exception{
Messenger messenger = new Messenger(SERVERIP, SERVERPORT, TIMEOUT, "UTF-8");
for (String requestXML : RequestXml) {
String response = messenger.sendReq(requestXML);
System.out.println(response);
messenger.close();
下面是我的socket发送类代码
public class Messenger {
private static final Logger logger = Logger.getLogger(Messenger.class);
private PrintW
private BufferedR
* 初始化连接
* @param serverIp
* @param serverPort
* @param timeout
* @param charset
* @throws Exception
public Messenger(String serverIp, int serverPort, int timeout, String charset) throws Exception {
this.soc = new Socket(serverIp, serverPort);
this.charset =
soc.setSoTimeout(timeout);
soc.setKeepAlive(true);
* 发送报文
* @param reqXML
待发送的报文
public String sendReq(String reqXML) {
StringBuffer responseStr = new StringBuffer("");
PrintWriter pw =
BufferedReader sin =
pw = new PrintWriter(new BufferedWriter(new OutputStreamWriter(soc.getOutputStream(), charset)));
sin = new BufferedReader(new InputStreamReader(soc.getInputStream(), charset));
("【开始发送报文】");
pw.println(reqXML);
pw.flush();
("【报文发送完毕】");
while((str = sin.readLine()) != null) {
responseStr.append(str);
("【成功读取响应报文】");
} catch(Exception e) {
logger.warn("【读取响应报文时出错】" + e);
} finally {
if (pw != null) {
pw.close();
if (sin != null) {
sin.close();
} catch (IOException e) {}
return responseStr.toString();
//关闭连接
public void close() {
if (pw != null) {
pw.close();
if (sin != null) {
sin.close();
} catch (IOException e) {}
if (soc != null) {
soc.close();
} catch (IOException e) {}
("【关闭SOCKET连接】");
按赞数排序
兄弟你这个问题解决了吗?我也碰到了,我快郁闷死了,换了流,设了超时间都不行,如果两个请求发的间隔很小的话才能正常收到,一长就收不到了,
你可以使用多点广播套接字
socket=new MulticastSocket(port);//port为端口
自己顶一下,没人遇到过这样的问题么
楼主解决了么,跪求啊
正遇到这个问题,求解啊
请问大神怎么解决socket问题
我的情况是
for循环socket请求
只响应最后一次的得到的数据 前面的没有数据返回
这是什么情况
其他相关推荐下次自动登录
现在的位置:
& 综合 & 正文
Socket超时机制
1 socket连接建立超时
socket连接建立是基于TCP的连接建立过程。TCP的连接需要通过3次握手报文来完成,开始建立TCP连接时需要发送同步SYN报文,然后等待确认报文SYN+ACK,最后再发送确认报文ACK。TCP连接的关闭通过4次挥手来完成,主动关闭TCP连接的一方发送FIN报文,等待对方的确认报文;被动关闭的一方也发送FIN报文,然等待确认报文。
正在等待TCP连接请求的一端有一个固定长度的连接队列,该队列中的连接已经被TCP接受(即三次握手已经完成),但还没有被应用层所接受。TCP接受一个连接是将其放入这个连接队列,而应用层接受连接是将其从该队列中移出。应用层可以通过设置backlog变量来指明该连接队列的最大长度,即已被TCP接受而等待应用层接受的最大连接数。
当一个连接请求SYN到达时,TCP确定是否接受这个连接。如果队列中还有空间,TCP模块将对SYN进行确认并完成连接的建立。但应用层只有在三次握手中的第三个报文收到后才会知道这个新连接。如果队列没有空间,TCP将不理会收到的SYN。
如果应用层不能及时接受已被TCP接受的连接,这些连接可能占满整个连接队列,新的连接请求可能不被响应而会超时。如果一个连接请求SYN发送后,一段时间后没有收到确认SYN+ACK,TCP会重传这个连接请求SYN两次,每次重传的时间间隔加倍,在规定的时间内仍没有收到SYN+ACK,TCP将放弃这个连接请求,连接建立就超时了。
JAVA Socket连接建立超时和TCP是相同的,如果TCP建立连接时三次握手超时,那么导致Socket连接建立也就超时了。可以设置Socket连接建立的超时时间-
connect(SocketAddress endpoint, int timeout)
如果在timeout内,连接没有建立成功,在TimeoutException异常被抛出。如果timeout的值小于三次握手的时间,那么Socket连接永远也不会建立。
不同的应用层有不同的连接建立过程,Socket的连接建立和TCP一样-仅仅需要三次握手就完成连接,但有些应用程序需要交互很多信息后才能成功建立连接,比如Telnet协议,在TCP三次握手完成后,需要进行选项协商之后,Telnet连接才建立完成。
2 socket读超时
如果输入缓冲队列RecvQ中没有数据,read操作会一直阻塞而挂起线程,直到有新的数据到来或者有异常产生。调用setSoTimeout(int timeout)可以设置超时时间,如果到了超时时间仍没有数据,read会抛出一个SocketTimeoutException,程序需要捕获这个异常,但是当前的socket连接仍然是有效的。
如果对方进程崩溃、对方机器突然重启、网络断开,本端的read会一直阻塞下去,这时设置超时时间是非常重要的,否则调用read的线程会一直挂起。
TCP模块把接收到的数据放入RecvQ中,直到应用层调用输入流的read方法来读取。如果RecvQ队列被填满了,这时TCP会根据滑动窗口机制通知对方不要继续发送数据,本端停止接收从对端发送来的数据,直到接收者应用程序调用输入流的read方法后腾出了空间。
3 socket写超时
socket的写超时是基于TCP的超时重传。超时重传是TCP保证数据可靠性传输的一个重要机制,其原理是在发送一个数据报文后就开启一个计时器,在一定时间内如果没有得到发送报文的确认ACK,那么就重新发送报文。如果重新发送多次之后,仍没有确认报文,就发送一个复位报文RST,然后关闭TCP连接。首次数据报文发送与复位报文传输之间的时间差大约为9分钟,也就是说如果9分钟内没有得到确认报文,就关闭连接。但是这个值是根据不同的TCP协议栈实现而不同。
如果发送端调用write持续地写出数据,直到SendQ队列被填满。如果在SendQ队列已满时调用write方法,则write将被阻塞,直到SendQ有新的空闲空间为止,也就是说直到一些字节传输到了接收者套接字的RecvQ中。如果此时RecvQ队列也已经被填满,所有操作都将停止,直到接收端调用read方法将一些字节传输到应用程序。
当Socket的write发送数据时,如果网线断开、对端进程崩溃或者对端机器重启动,TCP模块会重传数据,最后超时而关闭连接。下次如再调用write会导致一个异常而退出。
Socket写超时是基于TCP协议栈的超时重传机制,一般不需要设置write的超时时间,也没有提供这种方法。
&&&&推荐文章:
【上篇】【下篇】Java Socket通信(一)之客户端程序 发送和接收数据
作者:紫岩渊
字体:[ ] 类型:转载 时间:
对于Socket通信简述,服务端往Socket的输出流里面写东西,客户端就可以通过Socket的输入流读取对应的内容,Socket与Socket之间是双向连通的,所以客户端也可以往对应的Socket输出流里面写东西,然后服务端对应的Socket的输入流就可以读出对应的内容
网络应用分为客户端和服务端两部分,而Socket类是负责处理客户端通信的Java类。通过这个类可以连接到指定IP或域名的服务器上,并且可以和服务器互相发送和接受数据。
对于Socket通信简述,服务端往Socket的输出流里面写东西,客户端就可以通过Socket的输入流读取对应的内容。Socket与Socket之间是双向连通的,所以客户端也可以往对应的Socket输出流里面写东西,然后服务端对应的Socket的输入流就可以读出对应的内容。
例1:客户端的简略写法(一)。
Socket client =
client = new Socket(Ip,Port);
String msg="发送的数据内容!";
//得到socket读写流,向服务端程序发送数据
client.getOutputStream().write(msg.getBytes());
byte[] datas = new byte[2048];
//从服务端程序接收数据
client.getInputStream().read(datas);
System.out.println(new String(datas));
}catch(Exception e){
e.printStackTrace();
}finally {
if (client != null) {
client.close();
} catch (IOException e) {
System.out.println("systemerr:" +e);
例2:客户端简略写法(二)。
client = new Socket();
SocketAddress socketAddress = new InetSocketAddress(Ip,Port);
client.connect(socketAddress, 3000);
String msg="访问的服务器返回内容!";
//得到socket读写流,向服务端程序发送数据
client.getOutputStream().write(msg.getBytes());
byte[] datas = new byte[2048];
//从服务端程序接收数据
client.getInputStream().read(datas);
System.out.println(new String(datas));
}catch(Exception e){
e.printStackTrace();
}finally {
if (client != null) {
client.close();
} catch (IOException e) {
System.out.println("systemerr:" +e);
例3:客户端的完整写法。
//1.建立客户端socket连接,指定服务器位置及端口
Socket socket =new Socket(Ip,Port);
//2.得到socket读写流
OutputStream os=socket.getOutputStream();
PrintWriter pw=new PrintWriter(os);
InputStream is=socket.getInputStream();
BufferedReader br=new BufferedReader(new InputStreamReader(is));
//3.利用流按照一定的操作,对socket进行读写操作
String sendInfo="向服务器发送的数据信息!";
pw.write(sendInfo);
pw.flush();
socket.shutdownOutput();
//接收服务器的相应
String replyInfo=
while(!((replyInfo=br.readLine())==null)){
System.out.println("接收服务器的数据信息:"+replyInfo);
//4.关闭资源
br.close();
is.close();
pw.close();
os.close();
socket.close();
} catch (UnknownHostException e) {
e.printStackTrace();
} catch (IOException e) {
e.printStackTrace();
关于Java Socket通信(一)之客户端程序 发送和接收数据的相关知识,小编就给大家介绍到这里,更多信息请登陆脚本之家网站了解更多内容!
您可能感兴趣的文章:
大家感兴趣的内容
12345678910
最近更新的内容
常用在线小工具}

我要回帖

更多关于 socket循环接收数据 的文章

更多推荐

版权声明:文章内容来源于网络,版权归原作者所有,如有侵权请点击这里与我们联系,我们将及时删除。

点击添加站长微信