Windows的C++服务器和Android客户端用Socket通信,为什么会报IOException?

暗黑Zero 2015-03-04 12:40:30
Android中的接收线程是这样的:
	class GetThread implements Runnable
{
@Override
public void run()
{
try
{
BufferedReader in = new BufferedReader(new InputStreamReader(socket.getInputStream()));
while(true)
{
String input = in.readLine();
if(input!=null)
{
Message msg = new Message();
msg.obj = input;
handler.sendMessage(msg);
}
}
}
catch (IOException e)
{
System.out.println("NetThreadIOException");
Message msg = new Message();
msg.obj = "net error";
handler.sendMessage(msg);
}


Windows上的服务器我用了一份开源的库,主程序是这样的:
#include "Socket.h"
#include<iostream>
using namespace std;

const int PORT = 12121;
const int MAX_CONNECT = 100;

int main()
{
cout<<"Working..."<<endl;
SocketServer socket(PORT, MAX_CONNECT);
cout<<"Waiting for Client"<<endl;
socket.Accept();
socket.SendLine("Hello!");
cout<<"Hello!"<<endl;
system("pause");
return 0;
}


其中SendLine函数是这么写的:
void Socket::SendLine(std::string s) {
s += '/n';
send(s_,s.c_str(),s.length(),0);
}


现在现象是:打开服务器后,运行客户端,客户端能够正确连接至服务器,但是服务器发给他“Hello”时,客户端接收不到,并报IOException。

这份代码之前我曾在多个地方用过,只不过当时的服务器不同,一个是用Java写的,一个是用Linux的C++写的……

想知道出错的可能原因? 谢谢~~
...全文
232 4 打赏 收藏 转发到动态 举报
写回复
用AI写文章
4 条回复
切换为时间正序
请发表友善的回复…
发表回复
qq_33455714 2015-12-21
  • 打赏
  • 举报
回复
请问join()等待写在哪里 我也遇到了同样的问题
暗黑Zero 2015-03-04
  • 打赏
  • 举报
回复
引用 2 楼 dalor 的回复:
client_socket_manager.login();这句开的线程在login,马上就执行下一句 client_socket_manager.openGetThread(); 如果login的线程挂起或未login成功,那socket肯定是null,后面读信息,怎么读呢? 应该是确保login成功后,再oopenGetThread()。
谢谢,检查了一下,确实是这个的问题,我现在用join()等待LoginThread结束以后再执行openGetThread就没问题了~
开发者_android 2015-03-04
  • 打赏
  • 举报
回复
client_socket_manager.login();这句开的线程在login,马上就执行下一句 client_socket_manager.openGetThread(); 如果login的线程挂起或未login成功,那socket肯定是null,后面读信息,怎么读呢? 应该是确保login成功后,再oopenGetThread()。
暗黑Zero 2015-03-04
  • 打赏
  • 举报
回复
我试着修改了一下,发现如果把接收线程写在主Activity里面,程序就是正常工作的,这说明服务器那边没有问题:
public class MainActivity extends Activity 
{
	EditText ip_box;
	Button login_button;
	TextView text;
	Handler handler;
	final int port = 12121;
	ClientSocketManager client_socket_manager;
	Socket socket;
	String ip;
	
	@Override
	protected void onCreate(Bundle savedInstanceState) 
	{
		super.onCreate(savedInstanceState);
		setContentView(R.layout.activity_main);
		
		init();
		
		handler = new Handler()
		{
			public void handleMessage(Message msg)
			{
				String words = (String)msg.obj;
				if( words.equals("ok") == true )
				{
					Toast.makeText(MainActivity.this, "来自服务器的问候:登陆成功!!欢迎使用~",Toast.LENGTH_LONG).show();
					finish();
				}
				else if(words.equals("did not login") )
				{
					Toast.makeText(MainActivity.this,"ip错了或者是主机没有开", Toast.LENGTH_SHORT).show();
				}
				else
				{
					text.setText((String)msg.obj);
				}
			}
		};
		
		class GetThread implements Runnable //接收线程
		{
			public void getMsg()
			{
				try 
				{
					Scanner in = new Scanner(socket.getInputStream());
					String gotmsg = in.nextLine();
					Message msg = new Message();
					msg.obj = gotmsg;
					MainActivity.this.handler.sendMessage(msg);
					
				} catch (UnknownHostException e) 
				{
					Message msg = new Message();
					msg.obj = "net error";
					MainActivity.this.handler.sendMessage(msg);
				} catch (IOException e) 
				{
					Message msg = new Message();
					msg.obj = "net error";
					MainActivity.this.handler.sendMessage(msg);
				}
				
			}
			
			@Override
			public void run() 
			{
				try 
				{
					socket = new Socket();
					socket.connect(new InetSocketAddress(ip, port) , 5000);
				} catch (UnknownHostException e) 
				{
					Message msg = new Message();
					msg.obj = "did not login";
					MainActivity.this.handler.sendMessage(msg);
				} catch (IOException e) {
					Message msg = new Message();
					msg.obj = "did not login";
					MainActivity.this.handler.sendMessage(msg);
				}
				
				if( socket != null)
					getMsg();
				else
				{
					Message msg = new Message();
					msg.obj = "did not login";
					MainActivity.this.handler.sendMessage(msg);
				}
			}
		}
		
		login_button.setOnClickListener(new OnClickListener()
		{
			@Override
			public void onClick(View arg0) 
			{
				// TODO Auto-generated method stub
				ip = ip_box.getText().toString();
				client_socket_manager = new ClientSocketManager(ip, port, handler);
				boolean logged = client_socket_manager.login();
				GetThread g = new GetThread();
				new Thread(g).start();
			}
			
		});
	}

}
但是,我试图把网络操作分离出去的时候,就会出现IOException,分离之后的代码如下:
public class ClientSocketManager //管理网络的类
{
	String ip;
	int port;
	Socket socket;
	Handler handler; //通过这个handler发消息
	
	/**
	 * Thread to get message from server
	 * @author Zero
	 *
	 */
	class GetThread implements Runnable
	{
		@Override
		public void run() 
		{
			try 
			{
				BufferedReader in = new BufferedReader(new InputStreamReader(socket.getInputStream()));
				while(true)
				{
					String input = in.readLine();
					if(input!=null)
					{
						Message msg = new Message();
						msg.obj = input;
						handler.sendMessage(msg);
					}
				} 
			}
			catch (IOException e) 
			{
				System.out.println("NetThreadIOException");
				Message msg = new Message();
				msg.obj = "net error";
				handler.sendMessage(msg);
			}
			catch (NullPointerException e)
			{
				//System.out.println("NetThreadIOException");
				Message msg = new Message();
				msg.obj = "net error";
				handler.sendMessage(msg);
			}
		}
	}
	
	/**
	 * Thread to login to server
	 * @author Zero
	 *
	 */
	class LoginThread implements Runnable
	{
		boolean ok;
		@Override
		public void run() 
		{
			try 
			{
				socket = new Socket();
				socket.connect(new InetSocketAddress(ip, port) , 5000);
			} catch (UnknownHostException e) 
			{
				System.out.println("UnknownHostException");
				Message msg = new Message();
				msg.obj = "did not login";
				handler.sendMessage(msg);
				ok=false;
			} catch (IOException e) {
				System.out.println("IOException");
				Message msg = new Message();
				msg.obj = "did not login";
				handler.sendMessage(msg);
				ok=false;
			}
		}
	}
	
	public ClientSocketManager(){}
	
	/**
	 * Create a new ClientSocketManager
	 * @param _ip
	 * @param _port
	 * @param _handler
	 */
	public ClientSocketManager(String _ip, int _port, Handler _handler)
	{
		ip = _ip;
		port = _port;
		handler = _handler;
	}
	
	public boolean login()
	{
		LoginThread login_thread = new LoginThread();
		new Thread(login_thread).start();

		return login_thread.ok;
		
	}
	
	public void openGetThread()
	{
		GetThread getThread = new GetThread();
		new Thread(getThread).start();
	}
}

然后主Activity中:
login_button.setOnClickListener(new OnClickListener()
		{
			@Override
			public void onClick(View arg0) 
			{
				// TODO Auto-generated method stub
				ip = ip_box.getText().toString();
				client_socket_manager = new ClientSocketManager(ip, port, handler);
				boolean logged = client_socket_manager.login();
				//if(!logged)
				//	return;
				client_socket_manager.openGetThread();
			}
			
		});
这样就会在input = in.readLine()那一行爆出IOException。请问这是怎么回事?谢谢~~
内容概要:本文介绍了基于低秩逼近代理模型的N-1安全约束经济调度快速计算方法,并提供了完整的Matlab代码实现。该方法针对电力系统中N-1故障场景下的安全约束经济调度(SCED)问题,提出采用低秩逼近技术构建高效代理模型,有效降低高维优化问题的计算维度与复杂度,显著提升多场景下调度方案的求解效率。文中系统阐述了数学建模过程、代理模型构造原理、低秩近似算法推导及其实现流程,特别适用于含高比例可再生能源接入、存在大量不确定性因素的现代电力系统优化调度,能够在保障计算精度的同时满足实时性与准实时性应用需求。; 适合人群:具备电力系统分析、优化理论基础及Matlab编程能力的研究生、科研人员和工程技术人员,尤其适合从事电力系统经济调度、安全稳定分析、不确定性建模与高性能计算等相关领域的专业人士。; 使用场景及目标:①应用于大规模电力系统在N-1故障条件下的快速安全校核与经济调度决策支持;②为高渗透率新能源接入的电力系统提供高效的多场景优化求解方案;③支撑日前调度、实时调度等对计算速度与精度均有较高要求的工程应用场景。; 阅读建议:读者应结合所提供的Matlab代码深入理解算法实现细节,建议在标准测试系统上复现并调试程序,以掌握低秩逼近方法在电力系统优化中的具体应用技巧,并可根据实际研究方向进行模型拓展、性能对比与算法改进。
内容概要:本文档聚焦于电力系统黑启动与负荷恢复的研究,结合Matlab代码实现,系统探讨了电力系统在发生大面积停电事故后的恢复策略。研究内容涵盖了黑启动过程中的关键环节,如发电机组的启动顺序、恢复路径规划、负荷逐步投入等,并通过Matlab仿真对恢复流程进行建模与验证,旨在优化恢复时序与资源配置。文档还关联了智能优化算法、机器学习、路径规划、电力系统故障分析与调度优化等多种技术方向,展现了其在科研与工程实践中的广泛应用前景。配套代码和资料可通过提供的网盘链接下载,便于读者复现与拓展研究。; 适合人群:具备电力系统基本理论知识和Matlab编程能力的研究生、高校科研人员及从事电力系统运行、调度与控制相关工作的工程技术与研究人员。; 使用场景及目标:①用于电力系统恢复策略的教学演示与科研仿真分析;②支撑黑启动方案的设计、评估与优化决策;③为复杂电网故障后快速恢复供电提供算法模型与技术参考; 阅读建议:建议读者结合网盘中的完整代码资源,按照文档所述技术路线逐步实践,重点关注黑启动过程中机组启动逻辑与负荷恢复的协调机制,并可进一步拓展至多能源协同恢复、智能算法优化等前沿研究方向。
源码直接下载地址: https://pan.quark.cn/s/1eceaa56687c Chrome 开发者工具中文手册 =============== Chrome DevTools 是公认的优秀的前端调试工具,由于功能强大,所以使用起来有一定的学习门槛,与此同时 Chrome DevTools 暂时没有中文手册,对于不太熟悉英文的同学会比较吃力。 本项目的初衷是为想使用或者正在使用 Chrome DevTools 的同学提供一个中文手册,方便大家学习使用这个优秀的工具,提高前端开发效率和质量! 翻译流程 第一阶段 先将 Chrome DevTools 的内容按现有的目录结构翻译成中文,其中: 文章正文内容均放在 目录下,采用 格式。 文章中所用到的图片资源暂时先用现有英文手册的原始链接,后续图片资源会统一托管到七牛云存储 文件命名规则 文件名为 Chrome DevTools 对应文章超链接中 后的部分。 所有的空格和 用 代替。 例如: 这篇文档,对应 这个文件。 对于下级子页面文档,将其放在以父级文档名称命名的文件夹下面。 例如: 属于 那么将放置在 。 第二阶段 根据翻译文档,制作成类似在线手册或者与官方文档类似的网站,方便大家参阅。 参与项目 欢迎你参与翻译本项目,在翻译的过程中,可以锻炼你的英语能力和 Chrome DevTools 的实际应用能力,同时还为他人提供方便,何乐而不为? 一个个 commit 堆积起来就是一个了不起的 repo,欢迎你 Fork 并提交 Pull Request 或者 Issue ,哪怕是改正一个错别字、修正一个病句,我们都会很高兴。 参与方法和步骤如下: 登录 https://.com Fork 创建您的特性分支 (gi...

80,488

社区成员

发帖
与我相关
我的任务
社区描述
移动平台 Android
androidandroid-studioandroidx 技术论坛(原bbs)
社区管理员
  • Android
  • yechaoa
  • 失落夏天
加入社区
  • 近7日
  • 近30日
  • 至今
社区公告
暂无公告

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