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++写的……

想知道出错的可能原因? 谢谢~~
...全文
159 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。请问这是怎么回事?谢谢~~

80,350

社区成员

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

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