socket本地测试通过,打成jar包放到服务器上部分数据不能通信

书堂 发布于 2015/06/18 11:44
阅读 801
收藏 1

我先描述下项目:一个客户端(Android)、一个司机端(Adroid)、一个服务端(Java Socket),客户端和司机端连接服务端,保持长连接,通过业务完成通信。

(1)当客户端和司机端连接服务端本地电脑的ip和端口时可以正常通信,可以走完完整的流程。

(2)把服务端打成jar包,放到服务器上,服务器为linux系统的java环境,是裸环境,没有tomcat。

        1>第一步通信为身份验证,客户端与司机端都与socket通信正常;

        2>第二步通信为叫车,司机端与socket通信正常,客户端有时候能与socket正常通信,有时候却收不到socket返回的值,客户端和服务端都没有抛"任何异常"。应该不是网络的问题,因为放到外网服务器:阿里云上也出现这种状况;

我实在是想不通了,请教各位,有可能的原因是什么?下面贴代码:

客户端:就贴从socket读的部分

public class SocketService extends Service {
	SocketBean bean;
	Socket socket ;
	int flag = -1;
	boolean mark=true;//循环监听从服务器返回的数据的标志位
	BufferedReader reader ;
	BufferedWriter writer;
	private String s;
	String ss;
	
	
	@Override
	public void onCreate() {
		super.onCreate();
		System.out.println("=========onCreate===========");

		Thread thread = new Thread(new Runnable() {

			@Override
			public void run() {
				try {
					socket = new Socket("172.16.101.63",8088);//内网服务器

                                        reader = new BufferedReader(new InputStreamReader(socket.getInputStream()));
					writer = new BufferedWriter(new OutputStreamWriter(socket.getOutputStream()));
					
					sendFirst();
					
					while (mark) {
						s = reader.readLine();
						Log.i("tag", "从socket返回的值:"+s);//第二步不正常的时候这条语句也不打印
						if (s != null) {
							Message msg = Message.obtain();
							if (s.contains("error")) {
								msg.what = 1;
							}else if (s.contains("driver_count")) {//第二次返回司机数量
								msg.what=2;
							}else{//最后返回抢单成功或失败,返回的司机信息
								msg.what = 3;
							}
							msg.obj = s;
							handler.sendMessage(msg);
						}
					}
				} catch (UnknownHostException e) {
					e.printStackTrace();
				}catch (ConnectException e) {
					Log.i("tag", "socket连接异常");
					stopSelf();
				}catch (IOException e) {
					e.printStackTrace();
				}
			}

			/**
			 * 第一次发送身份验证
			 * @throws IOException
			 */
			private void sendFirst() throws IOException {
				User u = (User) AppManager.getAppManager().getCacheByKey(
						AppManager.CURRENT_USER_KEY);
				ss = null;
				ss ="{\"terminal\":0,\"app\":0,\"id\":" + u.getUser_id()
						+ ", \"name\":\"" + u.getUsername()
						+ "\", \"action\":0 }\r\n"; 
				writer.write(ss);
				writer.flush();
			}
		});
		thread.start();
	}

	
	@Override
	public int onStartCommand(Intent intent, int flags, int startId) {
		System.out.println("=========onStartCommand===========");
		bean = (SocketBean) intent.getSerializableExtra("msg");
		flag=intent.getIntExtra("flag", -1);
		if (flag==2) {//第一次启动socket不执行,第二次点击叫车时才执行
			ss = null;
			ss = jointMsg();//自己写的,拼接字符串
			try {
				writer.write(ss+"\r\n");
				writer.flush();
			} catch (IOException e) {
				e.printStackTrace();
			}
		}
		return super.onStartCommand(intent, flags, startId);
	}

	
	@Override
	public IBinder onBind(Intent intent) {
		return null;
	}
	
	@Override
	public boolean onUnbind(Intent intent) {
		return super.onUnbind(intent);
	}
	
	@Override
	public void onDestroy() {
		super.onDestroy();
		if (socket != null) {
			try {
				writer.close();
				reader.close();
				socket.close();
				Log.i("tag", "SocketService已关闭");//第二步不正常的时候也不打印此语句,什么都没打印
			} catch (IOException e) {
				Log.i("tag", "异常信息:"+e.getMessage());
				e.printStackTrace();
			}
		}
	}
	
}


司机端关键代码:


public class SocketService extends Service {
	private Socket socket;
	private OutputStreamWriter osw;
	private BufferedReader br;
	private String returnInfo;
	private int flag;// 收到信息的标志位
	private int flag_send;// 发出消息的标志位

	@Override
	public void onCreate() {
		super.onCreate();
		flag = 0;// 每次关闭socket后重新连接时flag=0
		new Thread() {
			@Override
			public void run() {
				try {
					socket = new Socket("172.16.101.63", 8088);// 内网服务器

					osw = new OutputStreamWriter(socket.getOutputStream());
					br = new BufferedReader(new InputStreamReader(socket.getInputStream()));

                                        // 获得要传递的车牌号、司机姓名与Id
					getDriveInfos();
					// 第一次发送请求,为验证身份
					String str = "{\"terminal\":0,\"app\":1,\"id\":" + driverId
							+ ", \"name\":\"" + driverName
							+ "\", \"plate_number\":\"" + carNum
							+ "\", \"action\":0 }\r\n";
					osw.write(str);
					osw.flush();
					while (true) {//在此处监听读
						returnInfo = br.readLine();
						if (returnInfo != null && !returnInfo.equals("")) {// 此处还要判断返回的值是不是空字符串
							++flag;
							Log.e("tag", flag + " -------- 返回的字符串=========:" + returnInfo);
							switch (flag) {
							case 1://第一次返回的数据
    								/*处理返回的数据 */
								break;
							case 2: //第二次返回的数据
                                                                /** 处理返回的数据 */                                                                 break;
							case 3://第三次返回的数据
								/*处理返回的数据*/
								break;
							default:
								break;
							}
						}
					}
				} catch (UnknownHostException e) {
					e.printStackTrace();
				} catch (IOException e) {
					e.printStackTrace();
				} catch (JSONException e) {
					e.printStackTrace();
				}
			}
		}.start();
	}

	@Override
	public int onStartCommand(Intent intent, int flags, int startId) {
		flag_send = intent.getIntExtra("flag", 0);
		Log.i("tag", "onStartCommand,flag_send=" + flag_send);
		switch (flag_send) {
		case 2:// 第二次向发送请求
			//发送的数据
			break;
		case 1:// 点击"结束状态"按钮时回到"抢单中"状态
			flag = 1;// 若再收到服务端发来的消息,则flag=2,然后显示“派单中"界面
			break;
		default:
			break;
		}
		return super.onStartCommand(intent, flags, startId);
	}

	@Override
	public void onDestroy() {
		super.onDestroy();
		if (socket != null) {
			try {
				osw.close();
				br.close();
				socket.close();
			} catch (Exception e) {
				e.printStackTrace();
			}
		}
		Log.i("tag", "SocketService已关闭");
	}

	@Override
	public IBinder onBind(Intent intent) {
		return null;
	}
}

服务端关键代码:


public class CustomerCallDriverService implements Runnable {
	private static Logger logger=Logger.getLogger(CustomerCallDriverService.class);
	
	private ClientGroup clientGroup=ClientGroup.getInstance();
	
	private Channel customerChannel=null;
	private CustomerCallDriverRequest request=null;
	private ConcurrentHashMap<String, Order> orders=null;
	
	private HttpClient httpClient;
	
	
	public CustomerCallDriverService(CustomerCallDriverRequest request,
			ConcurrentHashMap<String, Order> orders,
			HttpClient httpClient) {
		//根据请求的信息获取客户的channel
		customerChannel=clientGroup.findChannel(request.getId(),App.CUSTOMER);
		this.request=request;
		this.orders=orders;
		this.httpClient=httpClient;
	}
	
	@Override
	public void run() {
		//司机数量
		Integer driverCount=clientGroup.getDriver_channels().size();
		//TODO 查询OBD数据找到司机位置信息
		String json_data="";
		try{
			json_data=httpClient.findAroundDriver(request.getLocation().getLon(), request.getLocation().getLat(), 5+"");
			logger.info("OBD返回数据:"+json_data);
		if("".equals(json_data)){
			customerChannel.writeAndFlush("{\"error\":1,\"message\":\"附近没有司机\"}\r\n");
			return;
		}
		}catch(Exception ex){
			logger.error("请求OBD数据错误",ex);
			customerChannel.writeAndFlush("{\"error\":1,\"message\":\""+ex.getMessage()+"\"}\r\n");
			return;
		}
		List<Location>  driverLocations=getDriverLocation(json_data);
		
				
		StringBuffer sb=new StringBuffer("{\"driver_count\":"+driverLocations.size()+",\"dirver_locations\":");
		sb.append(JSON.toJSONString(driverLocations));
		sb.append("}\r\n");
		customerChannel.writeAndFlush(sb.toString());//给客户端发消息的语句

		//为司机发送广播
		StringBuffer sb_driver=new StringBuffer("{\"customer_location\":"+JSON.toJSONString(request.getLocation())+",");
		//拼接sb_driver,此处省略
		ChannelGroup dg = clientGroup.getDriver_channels();
		dg.writeAndFlush(sb_driver.toString());//给司机端发消息的语句	
		dg.clear();
		dg.close();	
	}
}



从服务器代码可以看到,给客户端和司机端发消息的语句都在同一个方法里,但是司机可以收到,客户有时候收到、有时候收不到,真是不知道了,拜托大家帮帮忙!!万分感谢!



      

加载中
0
书堂
为何没人来啊
0
书堂
没有大神吗?
返回顶部
顶部