请教socket如何解决发送端一股脑发送后,接收端的接收出错问题?

abigbigproblem 2018-02-03 09:37:29
是这样的,我想建立一条客户端与服务端的长连接
但却实际模拟过程中,发送端连续发送若干条数据,再让接收端延时接收,结果就会出现“Connection reset”的错误。

多次测试后发现若干的总结。
1、如果把接收端的延时取消,是可以正确的接收数据的。
2、如果在发送端添加关闭接口的操作(如加socket.close),接收端无论如何延时接收都不会发生问题。
但这样操作的话我就无法建立客户端与用户端的长连接了阿.............


import java.io.BufferedReader;
import java.io.BufferedWriter;
import java.io.InputStream;
import java.io.InputStreamReader;
import java.io.OutputStream;
import java.io.OutputStreamWriter;
import java.net.InetAddress;
import java.net.ServerSocket;
import java.net.Socket;

public class Temp {
public static void main(String[] args) throws Exception {
//TestServer(); // 这里先开启接收端,再开启发送端就可以了(如下图)
TestClient();
}

static void TestServer() throws Exception {
ServerSocket ss = new ServerSocket(8899);
System.out.println("等待连接中...");
Socket s = ss.accept();
InputStream is = s.getInputStream();

InputStreamReader isR = new InputStreamReader(is, "UTF-8"); // 这段是单字段接收
BufferedReader br = new BufferedReader(isR);
String strCom = "";

Thread.sleep(5000); // 设置延时接收。如果注释了这句和下面那句延时,就不会发生问题了......

while (true) {
// System.out.println(br.ready()); // 用于显示数据是否接收准备好,但实际发觉变化不定......
strCom = br.readLine();
if (" ".equals(strCom)) {
break;
}
System.out.println("接受内容:" + strCom);
Thread.sleep(1000);
strCom = "";
}

// ss.close(); // 接收端加不加这段影响不大。
}

static void TestClient() throws Exception {

InetAddress Address = InetAddress.getByName("127.0.0.1");
Socket socket = new Socket(Address, 8899);
OutputStream os = socket.getOutputStream();

BufferedWriter writer = new BufferedWriter(new OutputStreamWriter(os, "UTF-8"));
String content = "";

for (int i = 0; i < 10; i++) {
content = "A" + i;
writer.write(content);
writer.newLine();
writer.flush();
System.out.println("发送内容:" + content);
Thread.sleep(100);
}
writer.write(" ");
writer.newLine();
writer.flush();

// writer.close(); // 不能关闭流,一但关闭流会连带关闭socket
// System.out.println(socket.isClosed());
// socket.close(); // 如果加上这句,接收端无论如何延时都能顺利接收,但这样就无法建立长连接了..........
}
}








出错了。


实际试过添加
BufferedWriter.ready 来判断接收问题,结果不停的出现false,表明socket拒绝访问了........



...全文
1474 13 打赏 收藏 转发到动态 举报
写回复
用AI写文章
13 条回复
切换为时间正序
请发表友善的回复…
发表回复
abigbigproblem 2018-03-12
  • 打赏
  • 举报
回复
唉唉唉~!!!!终于找到问题的所在了!!!!!!!!!!!!!!!!!!!! 原来是我犯了一个相当低级的致命错误唉!!!这问题水了。
abigbigproblem 2018-02-14
  • 打赏
  • 举报
回复
引用 9 楼 oyljerry 的回复:
[quote=引用 8 楼 abigbigproblem的回复:][quote=引用 7 楼 oyljerry 的回复:] [quote=引用 5 楼 abigbigproblem的回复:][quote=引用 3 楼 oyljerry 的回复:] 心跳机制需要周期性发送一点数据来维持链接,从而长连接
这个我也是知道的,主要是在我在模拟网络延时接收时(上面的 Thread.sleep)发生了一但延时,就必定接收失败的情况。 所以我才提出,短连接或长连接如果单单的S→C或C→S,一但接收方发生了网络延时,就会发生出错的问题。(版主可以试试复制我的代码测试就明白的了) 话说回来,请问版主有没有 网络环境模拟的软件 推介?其实我也在想是否与使用 Thread.sleep 这个方法不当造成socket错误的...(但调低了Thread.sleep的时间好像又没有问题(10ms就不会产生socket错误....)) [/quote] 这还是因为延时引起网络连接断开了的样子[/quote] 如果就200ms的网络延时,基本上不会引起网络断开(单指网络内核连接本身) 如果是自己设定超时断开,一般也是设置10~30秒左右接收心跳不成功就断开。 但现在碰到的问题是,我模拟网络延时(用Thread.sleep测试),在发送端发送消息后,如果接收端只要超过10ms以上才接收消息就会发生错误。所以我才觉得这个问题比较辣手,如果我写完程序再发布那边的服务器,感觉是会出问题的。所以才上来问一下这里如何解决.......[/quote] 最好是模拟网络环境,而不是程序来sleep。这样可能测试准确点[/quote] 对,我也是这么想的,请问有模拟网络环境的软件推荐吗?网上是有一些的,但看介绍感觉是给html那边使用的.......
  • 打赏
  • 举报
回复
你需要用的是线程来延迟,而不是光等待 你那报的异常是reset,因为你是单线程的,第一次的数据都还没接受,就来第二个,之前的数据就没有了,所以异常。 用线程就不会出现这样的问题了
oyljerry 2018-02-13
  • 打赏
  • 举报
回复
引用 8 楼 abigbigproblem的回复:
[quote=引用 7 楼 oyljerry 的回复:] [quote=引用 5 楼 abigbigproblem的回复:][quote=引用 3 楼 oyljerry 的回复:] 心跳机制需要周期性发送一点数据来维持链接,从而长连接
这个我也是知道的,主要是在我在模拟网络延时接收时(上面的 Thread.sleep)发生了一但延时,就必定接收失败的情况。 所以我才提出,短连接或长连接如果单单的S→C或C→S,一但接收方发生了网络延时,就会发生出错的问题。(版主可以试试复制我的代码测试就明白的了) 话说回来,请问版主有没有 网络环境模拟的软件 推介?其实我也在想是否与使用 Thread.sleep 这个方法不当造成socket错误的...(但调低了Thread.sleep的时间好像又没有问题(10ms就不会产生socket错误....)) [/quote] 这还是因为延时引起网络连接断开了的样子[/quote] 如果就200ms的网络延时,基本上不会引起网络断开(单指网络内核连接本身) 如果是自己设定超时断开,一般也是设置10~30秒左右接收心跳不成功就断开。 但现在碰到的问题是,我模拟网络延时(用Thread.sleep测试),在发送端发送消息后,如果接收端只要超过10ms以上才接收消息就会发生错误。所以我才觉得这个问题比较辣手,如果我写完程序再发布那边的服务器,感觉是会出问题的。所以才上来问一下这里如何解决.......[/quote] 最好是模拟网络环境,而不是程序来sleep。这样可能测试准确点
abigbigproblem 2018-02-12
  • 打赏
  • 举报
回复
引用 7 楼 oyljerry 的回复:
[quote=引用 5 楼 abigbigproblem的回复:][quote=引用 3 楼 oyljerry 的回复:] 心跳机制需要周期性发送一点数据来维持链接,从而长连接
这个我也是知道的,主要是在我在模拟网络延时接收时(上面的 Thread.sleep)发生了一但延时,就必定接收失败的情况。 所以我才提出,短连接或长连接如果单单的S→C或C→S,一但接收方发生了网络延时,就会发生出错的问题。(版主可以试试复制我的代码测试就明白的了) 话说回来,请问版主有没有 网络环境模拟的软件 推介?其实我也在想是否与使用 Thread.sleep 这个方法不当造成socket错误的...(但调低了Thread.sleep的时间好像又没有问题(10ms就不会产生socket错误....)) [/quote] 这还是因为延时引起网络连接断开了的样子[/quote] 如果就200ms的网络延时,基本上不会引起网络断开(单指网络内核连接本身) 如果是自己设定超时断开,一般也是设置10~30秒左右接收心跳不成功就断开。 但现在碰到的问题是,我模拟网络延时(用Thread.sleep测试),在发送端发送消息后,如果接收端只要超过10ms以上才接收消息就会发生错误。所以我才觉得这个问题比较辣手,如果我写完程序再发布那边的服务器,感觉是会出问题的。所以才上来问一下这里如何解决.......
abigbigproblem 2018-02-12
  • 打赏
  • 举报
回复
引用 4 楼 liangbingbing123 的回复:
为什么要延时接收呢? 建立连接了直接发送接收不就行了? 怕断加心跳机制。
主要是我需要模拟网络的延时接收环境,像美国和我们这里传输,延时在200~1000ms左右的情况也有发生的。(我有ping美国洛杉矶那边的ip,都会有可能发生这情况的.....)
abigbigproblem 2018-02-12
  • 打赏
  • 举报
回复
引用 3 楼 oyljerry 的回复:
心跳机制需要周期性发送一点数据来维持链接,从而长连接
这个我也是知道的,主要是在我在模拟网络延时接收时(上面的 Thread.sleep)发生了一但延时,就必定接收失败的情况。 所以我才提出,短连接或长连接如果单单的S→C或C→S,一但接收方发生了网络延时,就会发生出错的问题。(版主可以试试复制我的代码测试就明白的了) 话说回来,请问版主有没有 网络环境模拟的软件 推介?其实我也在想是否与使用 Thread.sleep 这个方法不当造成socket错误的...(但调低了Thread.sleep的时间好像又没有问题(10ms就不会产生socket错误....))
oyljerry 2018-02-12
  • 打赏
  • 举报
回复
引用 5 楼 abigbigproblem的回复:
[quote=引用 3 楼 oyljerry 的回复:] 心跳机制需要周期性发送一点数据来维持链接,从而长连接
这个我也是知道的,主要是在我在模拟网络延时接收时(上面的 Thread.sleep)发生了一但延时,就必定接收失败的情况。 所以我才提出,短连接或长连接如果单单的S→C或C→S,一但接收方发生了网络延时,就会发生出错的问题。(版主可以试试复制我的代码测试就明白的了) 话说回来,请问版主有没有 网络环境模拟的软件 推介?其实我也在想是否与使用 Thread.sleep 这个方法不当造成socket错误的...(但调低了Thread.sleep的时间好像又没有问题(10ms就不会产生socket错误....)) [/quote] 这还是因为延时引起网络连接断开了的样子
初见_冰 2018-02-11
  • 打赏
  • 举报
回复
为什么要延时接收呢? 建立连接了直接发送接收不就行了? 怕断加心跳机制。
abigbigproblem 2018-02-03
  • 打赏
  • 举报
回复
呃....那目前找到网上所谓的长连接都有这样的问题阿....只要接收端延时接收,都会出现这样的问题阿....那谈何长连接呢............ (这事很正常阿?我连接美国LA的vps,延时都有200ms左右阿....)
oyljerry 2018-02-03
  • 打赏
  • 举报
回复
心跳机制需要周期性发送一点数据来维持链接,从而长连接
abigbigproblem 2018-02-03
  • 打赏
  • 举报
回复
好吧....在最后一次测试单条延时接收,原来只能接收端不马上接收,一样会出现相同的错误......唉....这样我就搞不懂了...........(马上发、马上收就不会出问题,一但延时接收就有问题了.....)

package 用于提问贴出代码;

import java.io.BufferedReader;
import java.io.BufferedWriter;
import java.io.InputStream;
import java.io.InputStreamReader;
import java.io.OutputStream;
import java.io.OutputStreamWriter;
import java.net.InetAddress;
import java.net.ServerSocket;
import java.net.Socket;

public class Temp2 {

	public static void main(String[] args) throws Exception {
		//TestServer();
		TestClient();
	}

	static void TestServer() throws Exception {
		ServerSocket ss = new ServerSocket(8899);
		System.out.println("等待连接中...");
		Socket s = ss.accept();
		InputStream is = s.getInputStream();	
		
		InputStreamReader isR = new InputStreamReader(is, "UTF-8");		// 这段是单字段接收
		BufferedReader br = new BufferedReader(isR);
		String strCom = "";
		
		
		Thread.sleep(5000);	// 设置延时接收。如果注释了这句和下面那句延时,就不会发生问题了......
		
		strCom = br.readLine();
		System.out.println("接受内容:" + strCom);
		
//		ss.close();	// 接收端加不加这段影响不大。
	}

	static void TestClient() throws Exception {

		InetAddress Address = InetAddress.getByName("127.0.0.1");
		Socket socket = new Socket(Address, 8899);
		OutputStream os = socket.getOutputStream();

		BufferedWriter writer = new BufferedWriter(new OutputStreamWriter(os, "UTF-8"));
		String content = "123456";
		writer.write(content);
		writer.newLine();
		writer.flush();
		System.out.println("发送内容:" + content);


//		writer.close();	// 不能关闭流,一但关闭流会连带关闭socket
//		System.out.println(socket.isClosed());
//		socket.close();	// 如果加上这句,接收端无论如何延时都能顺利接收,但这样就无法建立长连接了..........
	}
}

62,614

社区成员

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

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