前一段時間作項目,涉及到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>服務器端接收不到數據 :我使用的是校園網和實驗室的無線網,只有兩種狀況能夠接受到數據,第一種,服務器和手機終端鏈接在同一個路由器上;第二種服務器鏈接在校園網上,手機鏈接沒有限制。緣由暫時還不太清除