承接上文,达到监听端口,收发数据

11 篇文章 0 订阅
7 篇文章 0 订阅
public class PosInterfaceSocketThreadServer extends Thread{
	private static final Logger logger = Logger.getLogger(PosInterfaceSocketThreadServer.class);
	
	/**erp 地址与port*/
	private static final String ERP_IP = "127.0.0.1";
	private static final int ERP_PORT = 2000;
	
	private InetSocketAddress listen_address = null;
	
	private Selector selector = null;
	
	// posno  ip(存放posno,ip的map)
	private Map<String,SocketChannel> posChannelMap = null;
	
	public PosInterfaceSocketThreadServer(int port){
		listen_address = new InetSocketAddress(port);
		System.out.println(listen_address.getAddress().getHostAddress());
		init();
	}
	
	public PosInterfaceSocketThreadServer(String ip,int port){
		listen_address = new InetSocketAddress(ip, port);
		init();
	}
	
	private void init(){
		try{
			//获取一个ServerSocket通道
	        ServerSocketChannel serverChannel = ServerSocketChannel.open();
	        serverChannel.configureBlocking(false);
	        serverChannel.socket().bind(listen_address);
	        //获取通道管理器
	        selector=Selector.open();
	        //将通道管理器与通道绑定,并为该通道注册SelectionKey.OP_ACCEPT事件,
	        //只有当该事件到达时,Selector.select()会返回,否则一直阻塞。
	        serverChannel.register(selector, SelectionKey.OP_ACCEPT);
		}catch(IOException e){
			e.printStackTrace();
		}
	}
	
	public void run(){
		try{
			
			//String posAddress = StringUtils.EMPTY;
            //int posPort = 0;
            //InetSocketAddress pos_address = null;
			SocketChannel channel = null;
			
			//使用轮询访问selector
	        while(true){
	            if(selector.select() == 0){
	            	continue;
	            }
                
	            // 获取selector中的迭代器,选中项为注册的事件
	            Iterator<SelectionKey> ite=selector.selectedKeys().iterator();
	            while(ite.hasNext()){
	                SelectionKey key = ite.next();
	                //删除已选key,防止重复处理
	                ite.remove();
	                
	                // 客户端请求连接事件
	                if(key.isAcceptable()){
	                	// 判断erp服务器是否开启,如果开启,则接受数据;没有开启,则直接向客户端发送“erp服务没有开启!”
	                	boolean is_erp_open = true;
	                	try{
	                		new Socket(ERP_IP,ERP_PORT);
	                	}catch(IOException e){
	                		is_erp_open = false;
	                	}

	                    ServerSocketChannel server = (ServerSocketChannel)key.channel();
	                    
	                    //获得客户端连接通道
	                    channel = server.accept();
	                    Socket acceptSocket = channel.socket();
	                    System.out.println("客户端地址与IP:"+acceptSocket.getInetAddress().getHostAddress() + "\t"+acceptSocket.getPort());
	                    
	                    // 获得连接的ip地址
	                    //posAddress = acceptSocket.getInetAddress().getHostAddress();
	                    //posPort = acceptSocket.getPort();
	                    
	                    // 设置通道为非阻塞
	                    channel.configureBlocking(false);
	                    
	                    if(is_erp_open == false){
	                    	//向客户端发消息
		                    channel.write(ByteBuffer.wrap(new String("erp 服务没有开启,请确认!").getBytes()));
	                    }
	                    
	                    //在与客户端连接成功后,为客户端通道注册SelectionKey.OP_READ事件。
	                    channel.register(selector, SelectionKey.OP_READ);
	                    
	                    System.out.println("客户端请求连接事件");
	                }else if(key.isReadable()){       	
	                	//有可读数据事件
	                    //获取客户端传输数据可读取消息通道。
	                    channel = (SocketChannel)key.channel();
	                    //创建读取数据缓冲器
	                    ByteBuffer buffer = ByteBuffer.allocate(1024);
	                    channel.read(buffer);
	                    byte[] data = buffer.array();
	                    String message = new String(data);
	                    
	                    if(buffer.position() != 0){
	                    	System.out.println("从pos/erp端获得数据, size:" + buffer.position() + " msg: " + message);
	                    	
	                    	String infoPosition = message.split("\\$")[0];
	                    	String infoBean = message.split("\\$")[1];
	                    	JSONObject posInfo = JSONObject.fromObject(infoBean);
                    		Iterator<String> posKeys = posInfo.keys();
                    		String posno = StringUtils.EMPTY;
                    		while(posKeys.hasNext()){
                    			String posKey = (String) posKeys.next();
                    			if("posno".equals(posKey)){
                    				posno = (String)posInfo.get(posKey);
                    			}
                    		}
	                    	if(infoPosition.contains("CERTIFY")){
	                    		// 判断如果是从pos端获得数据,则posno ip 存放入posInfoMap中,并将发送请求发送给erp
	                    		if(null == posChannelMap || 0 == posChannelMap.size()){
	                    			posChannelMap = new HashMap<String,SocketChannel>();
	                    			//pos_address = new InetSocketAddress(posAddress, posPort);
	                    			posChannelMap.put(posno, channel);
	                    		}else{
	                    			if(posChannelMap.containsKey(posno)){
	                    				// 向客户端发消息 posno冲突,请确认!
	                    				sendErpSocketMessage(ERP_IP,ERP_PORT,"posno冲突,请确认!");
	                    				
	        		                    // 设置为下一次读取或是写入做准备
	        		                    key.interestOps(SelectionKey.OP_READ | SelectionKey.OP_WRITE);
	        		                    return;
		                    		}else{
		                    			posChannelMap.put(posno, channel);
		                    		}
	                    		}
	                    		
	                    		// 发送消息给erp
	                    		sendErpSocketMessage(ERP_IP,ERP_PORT,message);
	                    	}else if(infoPosition.contains("INFO")){
	                    		// 判断如果是从erp端获得数据,则根据返回的posno发送给相应客户端
	                    		if(null != posChannelMap && 0 != posChannelMap.size()){
	                    			// TODO
	                    			posno = "0002";
	                    			// 发送消息给pos
                    				SocketChannel pos_socket_address = posChannelMap.get(posno);
		                    		sendPortSocketMessage(pos_socket_address,message);
	                    		}
	                    	}
	                    	
		                    // 设置为下一次读取或是写入做准备
		                    key.interestOps(SelectionKey.OP_READ | SelectionKey.OP_WRITE);
	                    }
	                }
	            }
	        }
		}catch(Exception e){
			e.printStackTrace();
		}
	}
	
	/**
	 * 发送消息给erp
	 * @param ip
	 * @param port
	 * @param receiveMessage
	 * @return
	 */
	private void sendErpSocketMessage(String ip,int port,String receiveMessage){
		try{
			Socket socket = new Socket(ip,port);
			
			// 发送给erp或者客户端
			OutputStreamWriter outputStreamWriter = new OutputStreamWriter(socket.getOutputStream(),"UTF-8");
		    outputStreamWriter.write(receiveMessage);
		    outputStreamWriter.flush();
	
		    // 从erp中接受数据
		    /*InputStreamReader inputStreamReader = new InputStreamReader(socket.getInputStream(),"UTF-8");
		    String barcode_json = "";
		    int msg = 0;
		    while((msg = inputStreamReader.read()) != -1){
		    	barcode_json += (char)msg;
		    }
		    return barcode_json;*/
		    socket.close();
		}catch(IOException e){
			e.printStackTrace();
		}
	}
	
	/**
	 * 发送消息给pos
	 * @param socketChannel
	 * @param message
	 * @throws UnsupportedEncodingException 
	 */
	private void sendPortSocketMessage(SocketChannel socketChannel,String message) throws Exception{
		/*ByteBuffer buffer = ByteBuffer.wrap(message.getBytes("UTF-8"));
		socketChannel.write(buffer);
		buffer.flip();
		buffer.clear();*/
		
		byte[] bytes = message.getBytes(); 
        ByteBuffer writeBuffer = ByteBuffer.allocate(bytes.length); 
        writeBuffer.put(bytes); 
        writeBuffer.flip(); 
        socketChannel.write(writeBuffer); 
	}
	
}

评论 1
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值