最近在學習Java網路編程,之前聽說過,但一直都沒有認真了解過。這幾天突然來了興致,覺得很神奇,忽然就想要了解下具體是什麼個情況。
Socket通常也稱為"套接字",用於描述IP位址和端口,是一個通訊鏈的句柄。在Internet上的主機一般運行了多個服務軟體,同時提供幾種服務。每種服務都開啟一個Socket,並綁定到一個連接埠上,不同的連接埠對應於不同的服務。
Socket非常類似電話插座。以一個國家級電話網為例,電話的通話雙方相當於相互通訊的2個進程,區號是它的網路位址;區內一個單位的交換機相當於一台主機,主機分配給每個用戶的局內號碼相當於Socket號。任何用戶在通話之前,首先要佔有一部電話機,相當於申請一個Socket;同時要知道對方的號碼,相當於對方有一個固定的Socket。然後向對方撥號呼叫,相當於發出連線請求(如果對方不在同一區內,還要撥對方區號,相當於給網路位址)。假如對方在場並空閒(相當於通訊的另一主機開機且可以接受連線要求),拿起電話話筒,雙方就可以正式通話,相當於連線成功。雙方通話的過程,是一方向電話機發出訊號和對方從電話機接收訊號的過程,相當於向Socket發送資料和從socket接收資料。通話結束後,一方掛起電話機相當於關閉Socket,撤銷連線。
在電話系統中,一般使用者只能感受到本地電話機和對方電話號碼的存在,建立通話的過程,文字傳輸的過程以及整個電話系統的技術細節對他都是透明的,這也與Socket機制非常相似。 Socket利用網間網路通訊設施實現進程通信,但它對通訊設施的細節毫不關心,只要通訊設施能提供足夠的通訊能力,它就滿足了。
以上這些都是百度百科裡面的定義與解釋,不過看著也還蠻容易理解的,不像之前有的解釋很不容易理解,專業術語太多,理解起來特別費力。
Socket通訊實現步驟:
1、建立ServerSocket與Socket
2、開啟連接Socket的對Socket進行讀寫作業
4、關閉輸入/輸出流,並關閉Socket
下面是一個例子,客戶端讀寫與服務端讀寫
服務端程式碼
public class Server { public static void main(String args[]) throws IOException { //定义一个ServerSocket监听在端口8888上 int port = 8888; int i=1; //连接计数 //server尝试接收其他Socket的连接请求, ServerSocket server = new ServerSocket(port); //server的accept方法是阻塞式的 ,即等待着客户端的请求 Socket socket = server.accept(); System.out.println("连接"+i++); //跟客户端建立好连接,我们就可以获取socket的InputStream,从中读取客户端发过来的信息。 Reader reader = new InputStreamReader(socket.getInputStream()); char chars[] = new char[64]; int len; StringBuilder sb = new StringBuilder(); String temp; int index; while ((len=reader.read(chars)) != -1) { temp = new String(chars, 0, len); if ((index = temp.indexOf("eof")) != -1) { //遇到eof时就结束接收 sb.append(temp.substring(0, index)); break; } sb.append(temp); } System.out.println("from client: " + sb); //读完后写数据 Writer writer = new OutputStreamWriter(socket.getOutputStream()); writer.write("Hello Client:我是服务端输入数据"); //释放资源 writer.flush(); writer.close(); reader.close(); socket.close(); server.close(); } }
注意點
在上述代码中,当服务端读取到客户端发送的结束标记,即“eof”时就会结束数据的接收,终止循环,这样后续的代码又可以继续进行了。
public class Client { public static void main(String args[]) throws Exception { //为了简单起见,所有的异常都直接往外抛 String host = "192.168.74.1"; //要连接的服务端IP地址 int port = 8888; //要连接的服务端对应的监听端口 //与服务端建立连接 Socket client = new Socket(host, port); //建立连接后就可以往服务端写数据了 Writer writer = new OutputStreamWriter(client.getOutputStream()); writer.write("Hello ,我是客户端输入数据"); writer.write("eof"); writer.flush();//写完后要记得flush //读取来自服务端数据 Reader reader = new InputStreamReader(client.getInputStream()); char chars[] = new char[64]; int len; StringBuffer sb = new StringBuffer(); String temp; int index; while ((len=reader.read(chars)) != -1) { temp = new String(chars, 0, len); if ((index = temp.indexOf("eof")) != -1) { sb.append(temp.substring(0, index)); break; } sb.append(new String(chars, 0, len)); } System.out.println("from server: " + sb); writer.close(); reader.close(); client.close(); } }
过程:先是给服务端发送了一段数据,之后读取服务端返回来的数据,跟之前的服务端一样在读的过程中有可能导致程序一直挂在那里,永远跳不出while循环,解决方法和服务端一样,用一个结束标志。
对于客户端往Socket的输出流里面写数据传递给服务端要注意一点,如果写操作之后程序不是对应着输出流的关闭,而是进行其他阻塞式的操作(比如从输入流里面读数据),记住要flush一下,只有这样服务端才能收到客户端发送的数据,否则可能会引起两边无限的互相等待。在稍后讲到客户端和服务端同时读和写的时候会说到这个问题。
以上是Java網路程式設計的一些心得的詳細內容。更多資訊請關注PHP中文網其他相關文章!