前一段时间作项目,涉及到TCP和UDP的使用,长期作单机的东西,一下跳到网络真的不适应,记录一下这些东西的入门级使用。java
整体来讲,TCP和UDP的使用流程分三步,只是TCP和UDP使用的类有所不一样服务器
图一 整体流程网络
具体使用的类在表一中列出,TCP是使用流传输,而UDP将数据打包发送。socket
TCP/IP | UDP | |
Socket | Scoket | DatagramSocket |
Outputstream | DataOutputStream/PrintWirter | DatagramPacket |
send | Outputstrem.flush(); | DatagramPacket.send |
客户端-TCP使用方法
spa
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使用方法code
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获取数据。server
服务器端 - 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;
服务器端-UDPip
//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>服务器端接收不到数据 :我使用的是校园网和实验室的无线网,只有两种状况能够接受到数据,第一种,服务器和手机终端链接在同一个路由器上;第二种服务器链接在校园网上,手机链接没有限制。缘由暂时还不太清除