Android网络通信Socket使用

      前一段时间做项目,涉及到TCP和UDP的使用,长期做单机的东西,一下跳到网络真的不适应,记录一下这些东西的入门级使用。

      总体来说,TCP和UDP的使用流程分三步,只是TCP和UDP使用的类有所不同

Android网络通信Socket使用

图一 总体流程

        具体使用的类在表一中列出,TCP是使用流传输,而UDP将数据打包发送。


TCP/IP UDP
Socket Scoket DatagramSocket
Outputstream DataOutputStream/PrintWirter DatagramPacket
send Outputstrem.flush(); DatagramPacket.send
        其中有些地方还是比较困惑的:DataOutputStream/PrintWirter有什么区别呢?

  客户端-TCP使用方法

                Socket socket = null;
		DataOutputStream out = null;
		//DataInputStream in = null;

		try {
			//Socket实例化
			socket = new Socket();
			//IP地址对象构造
			InetAddress addr = Inet4Address.getByName(ip);
			//1)Socket链接服务器(指明端口和IP)
			socket.connect(new InetSocketAddress(addr, port));
			////设置超时限制(未使用)
			// socket.setSoTimeout(2000);
			//2)获取Socket对象的OutputStream
			out = new DataOutputStream(socket.getOutputStream());
			//in = new DataInputStream(socket.getInputStream());
			if (out != null) {
				//特殊格式(可以忽略)
				String value = msg;
				byte[] data = value.getBytes();
				int size = data.length;

				byte[] bt = new byte[4];
				bt[0] = (byte) size;
				bt[1] = (byte) (size >> 8);
				bt[2] = (byte) (size >> 16);
				bt[3] = (byte) (size >> 24);
				//写入数据
				out.write(bt);
				out.write(data);
				//3)传输数据
				out.flush();

			}
		} catch (Exception e) {
			// System.out.println(e.getMessage());
		} finally {
			try {
				if (out != null)
					out.close();
				//if (in != null)
					//in.close();
				if (socket != null)
					socket.close();
			} catch (IOException e) {
			}
		}

   客户端-UDP使用方法

DatagramSocket socket;
		try {
			//特殊格式(可以忽略)
			byte[] data = msg.getBytes(charset);
			int size = data.length;

			byte[] bt = new byte[4];
			bt[0] = (byte) size;
			bt[1] = (byte) (size >> 8);
			bt[2] = (byte) (size >> 16);
			bt[3] = (byte) (size >> 24);

			//1)DatagramSocket对象实例化
			socket = new DatagramSocket();
			//IP地址对象实例化
			InetAddress ipAdress = InetAddress.getByName(ip);
			//2)构造DatagramPacket对象,用于封装和发送数据
			DatagramPacket packet = new DatagramPacket(data, data.length,
					ipAdress, port);
			//3)数据发送
			socket.send(packet);
			socket.close();
		} catch (SocketException e) {
			// TODO Auto-generated catch block
			e.printStackTrace();
		} catch (IOException e) {
			// TODO Auto-generated catch block
			e.printStackTrace();
		}

  服务器接收端TCP需要通过ServerSocket与设备端口进行链接,接收Socket利用InputStream获取数据;UDP依然利用DatagramSocket与端口链接,DatagramPacket获取数据。

   服务器端 - TCP

ServerSocket serverSocket=new ServerSocket(12345);
System.out.println("Create Serversocket");
////设置超时(未使用)
//serverSocket.setSoTimeout(5000);
//2>接受Socket
Socket socket=serverSocket.accept();
System.out.println("accept");
//3>获取Socket的InoutStream
InputStream input=socket.getInputStream();
byte[] buffer=new byte[1024*4];
//4>读取数据
input.read(buffer);
System.out.print(new String(buffer).trim());
//5>关闭Socket
socket.close();
serverSocket.close();
serverSocket=null;

   服务器端-UDP

//1>构建DatagramSocket链接端口
DatagramSocket socket=new DatagramSocket(12345);
byte[] buffer=new byte[1024];
//2>构建DatagramPacket用于接收数据
DatagramPacket packet=new DatagramPacket(buffer, buffer.length);
//3>获取数据
socket.receive(packet);
System.out.println("Receive");
//4>设置偏移量的方法,解决了传输数据中的乱码问题
System.out.println(new String(packet.getData(),packet.getOffset(),packet.getLength()));
//5>一定要关闭,否则影响下次使用
socket.close();

常见问题:

    1>ECONNREFUSED 问题 :这个问题困扰了我好久,其实处理起来比较容易,产生的原因是端口被占,或者ip错误,需要仔细检查IP和端口号,端口号可以设置大一些,1024一下的端口号容易被占用。

    2>程序在socket创建或连接的时候程序崩溃 :我出现这种情况大多是服务器没有开,并且使用的TCP协议,打开就好了

    3>服务器端接收不到数据 :我使用的是校园网和实验室的无线网,只有两种情况可以接受到数据,第一种,服务器和手机终端连接在同一个路由器上;第二种服务器连接在校园网上,手机连接没有限制。原因暂时还不太清除


你可能感兴趣的:(Android网络通信Socket使用)