Java TCP 编程简介
一.TCP 協議簡介
http://blog.csdn.net/nvd11/article/details/40954043
之前的博文簡單介紹了網絡編程中的UDP協議
其實更常用的網絡協議是TCP協議.
* UDP協議是不可靠的, 因為UDP協議類似與發郵件, 發送者不會關心接受者的狀態. 總之發就是了. 接受者能不能收到是他的事情...? 也就是說郵件是有幾率會丟失的.
* 而TCP協議是相對可靠的, 類似于打電話, 發送方首先要跟接收方打通1條連接通道(類似首先要打通電話), 然后才能通過這條通道發送信息.? 如果接受者不在線, 發送者是無法發送信息的.?
? 也就是將大大保證了發送的每條信息, 接受者都能get到.
二.TCP 的若干個名詞概念
信息要傳輸, 必須要有兩個party, 分別是發送方和接收方.而 TCP協議, 發送方和接收方地位是相對的, 也就是說A可以發送信息給B, B也可以發送信息給A.
也就沒有發送和接受方的概念了, 可以把A,B可以理解成兩個終端.
但是TCP信息雙方的兩個終端(程序)是可以分成Server端和Client端的.
2.1 Client 程序
好了, 既然信息的兩端可以分成Client和Server, 它們之間可以互相發送接受信息, 那么到底是誰是Client, 誰是Server呢.
實際上, 我們定義:
首先發送連接請求的是Client.
就如A電話給B, B接通后它們就可以聊天了,? 這時我們認為A是Client, B是Server.
2.2 Server 程序
Server端就是待接通的一方了.
Server端有一個好明顯的特性, 也就是將Server端必須長期保持監聽(listening)狀態.? 通俗地講, Server端的程序必須保持在線.
就如A給B打電話, 作為B, 必須保持電話在線.
而A作為Client, 只需要想打電話時開機就得了. 平時關機也沒關系.
2.3 Client - Server - Client
很多時, Client的目的不是想跟Server通信, 而是跟另1個Client通信.
這時, Server就作為1個信息中轉的作用.
注意, 這時實際上有兩個 TCP通迅的行為了.
分別是Client A 和 ServerB
??????? 和ClientC 和 ServerB
但效果看起來就如A跟C在通信.
地球上大多數聊天工具都是這種模式的.? 一旦ServerB掛了, 就不能用了..
2.4 IP地址
TCP協議中, IP地址同樣是作為表示網絡機器的作用, 就如打電話雙方中的電話號碼.
究竟要把信息發送到哪里.??? 作為Server, ip地址一般是固定的, 但是Client則不是.
2.5 端口(Port)
端口表示某條信息到底要發送給制定計算機中的哪1個程序.
例如一個Server 程序B正在監聽端口12345,? 則所有發送給這個端口的信息, 操作系統都會把這些信息交給這個B程序
但是發送到這個臺計算機的另1個端口的信息,? 這個B程序是不知道的.
2.6 監聽(listening)
監聽這個名詞相信大家經常見到.
實際上監聽代表1個程序里面有1個循環.
這個循環在不斷地"嘗試" 從某個指定端口接受信息.
簡單地講, 如果程序B正在監聽端口12345,? A就發送到這個端口的信息(適當的協議), B都會收到.
但是如果B程序沒在監聽, 甚至被關閉沒在執行, 則收不到這個端口的信息了.
2.7 通道.
我們上面說過, TCP協議兩個終端 通信前提是 打通它們之間的通信通道.
實際上,? 一條通道的信息傳輸方向是單向的.
所以TCP協議的兩個終端之間實際上會有兩條通道, 一條是A通向B的, 另一條是B通向A的.
在編程中, 這兩條通道實際上就是兩條方向相反的Stream.
對于終端A, 一條是InputStream, 另一條是OutputStream
對于終端B, A的InputStream就是B的OuputStream,? A的OutputStream就是B的InputStream.
2.8 數據字節流Stream
我的博客里有若干關于流(Stream)的博文,? 如果不懂什么是流的讀者, 沒必要往下看了, 強烈建議先去弄懂什么是流.
三.Java TCP協議中的 若干個關鍵類
3.1 Socket
Socket這個詞大家也經常見啦, 它的中文名是"套接字",? 很難理解啊, 下面都直接用Socket來稱呼它了.
Socket實際就是上面所說的"終端" 程序所使用的發送和接受信息用的工具.
Socket里面有兩個關鍵方法,
分別是getOutputStream() 和 getInputStream().'
很明顯, Socket里面的兩條數據流才是通訊的關鍵嘛.
也就是將Socket只不過是程序中使用的一個類, 這個類用于使用TCP協議來發送接受數據.
3.2 ServerSocket
只看這個詞, 肯定是與Server有關了,
實際上ServerSocket 是 Server程序中, 用于創建Socket(上面那個類)的一個工廠.
如果在Client端, 我想創建1個Socket對象, 直接用Socket 類的new()方法, 然后制定目標ip和端口,
一旦Socket的對象創建, 則回自動向目標(Server)發送連接請求
但是Server端則必須用ServerSocket的? accept()方法來監聽, 一旦收到連接請求.
則會生成Server端的Socket對象,? 這個Socket 對象 與 Client端的Socket對象之間就會有兩條打通了的方向相反的數據流.
四.一個簡單的Java TCP協議小程序
這個程序真的是很簡陋的, 它有兩個類TCPServer1 和 TCPClient1
一旦TCPServer1被執行,? 則它會監聽某個指定端口(10019)
一旦TCPClient1被執行, 它會向Server端的10019發送一條信息,? Server收到這個信息后會返回一條確認信息回給Client端..
4.1 TCPServer1.java
import java.net.ServerSocket; import java.net.Socket; import java.io.*;public class TCPServer1{private static int port = 10019;public static void main(String[] args){try{tcpServer();}catch(Exception e){e.printStackTrace(); }}public static void tcpServer() throws Exception{//ServerSocket is Factory of Socket, ServerSocket ss = new ServerSocket(port);//a loop to list the portwhile(true){//Function accept is a blocking method, will listing the port, untill get a connect//request from a client. it means if no any request form client,//the program will keep waiting here...////After got a connect request from a client, the ServerSocket will package//the connection to a Socket Object ////The socket.getInputStream of Server is the same one with the socket.getOutputStream of Client.//The socket.getOutputStream of Server is the same one with the socket.getInputStream of Client.Socket s = ss.accept();System.out.println("A connection is setup!");//get a feedback to clentDataInputStream dis = new DataInputStream(s.getInputStream());//print the message from client, readUTF() is also a blocking method.System.out.println(dis.readUTF()); //send a feedback to client.DataOutputStream dos = new DataOutputStream(s.getOutputStream());dos.writeUTF("Your message is sent to Server successfully!");dis.close();dos.close();s.close();}} }
里面的內容大部分是注釋啦
流程很簡單,
首先建立1個ServerSocket對象,
然后循環監聽端口10019.
一旦受到連接請求, 就建立1個Socket對象,?
然后嘗試接受1條信息.
然后發送給Client端1條信息.
最后關閉資源
在這個循環中.
每次受到鏈接請求都有1個Socket對象生成.
所以一般在Server端,?? ServerSocket的對象只會有1個
但是Socket對象可能會有多個,? 它們分別對應不同Client端.
所以作為網絡服務器的Server一定要足夠強大, 生產中它必須同時跟多個Client通訊, 而Client實際上只會同1個Server通訊.(或者說利用Server間接地跟其他Client通訊)
值得注意的是s.accept()方法.
這個是1個阻塞方法, 除非受到1個連接請求, 否則程序會卡在這個方法一直等待..
4.2 TCPClient1.java
import java.net.Socket; import java.io.*;public class TCPClient1{public static String targetIP = "192.168.1.107";public static int port = 10019;public static void main(String[] args){try{tcpClient();}catch(Exception e){e.printStackTrace();} }public static void tcpClient() throws Exception{//Once the Socket Object is created, it will send the connect request to//Server, if the connection failed to connect, will prompt excepions..////yes, it needs the listing method(socket.accept()) running in Server side.Socket s = new Socket(targetIP, port);//if no any exception//Send a message to ServerDataOutputStream dos = new DataOutputStream(s.getOutputStream());dos.writeUTF("Hi Server!");dos.flush();//try to get message from ServerDataInputStream dis = new DataInputStream(s.getInputStream());System.out.println(dis.readUTF());dos.close();dis.close();s.close();} }上面的s.accept()方法在等待什么?
就是等待Client端的 Socket 類的構造方法啊.
看看下面這句代碼
Socket s = new Socket(targetIP, port);Client端的Socket直接使用構造方法創建.
但是
* 必須制定目標(Server)的ip和端口
* Server端必須有程序在監聽這個端口.
一旦發現Server端有程序在監聽, 則這個對象就會成功創建.
后面就是流的事情了.
否則, 如果Server端那個端口沒有程序在監聽, 則構造方法會拋出異常...
4.3 執行
分別compile它們成兩個類.
放在局域網的兩臺機器上執行(一臺是虛擬機).
就可以看出效果了:
總結
以上是生活随笔為你收集整理的Java TCP 编程简介的全部內容,希望文章能夠幫你解決所遇到的問題。
- 上一篇: Java xml 工具 JDOM 使用
- 下一篇: WebServer 软件原理简介