可以這樣說:我們在網(wǎng)絡(luò)上只做一件事,利用各種軟件沒完沒了的相互通信。
?????? 對于單機(jī)系統(tǒng)而言,進(jìn)程在系統(tǒng)中有自己唯一的進(jìn)程號。 但在網(wǎng)絡(luò)環(huán)境下,各主機(jī)獨(dú)立分配的進(jìn)程號不能唯一標(biāo)識該進(jìn)程。例如,主機(jī)A賦于某進(jìn)程號5,在B機(jī)中也可以存在5號進(jìn)程,因此,“5號進(jìn)程”這句話就沒有意義了。而且 ? 操作系統(tǒng)支持的網(wǎng)絡(luò)協(xié)議眾多,不同協(xié)議的工作方式不同,地址格式也不同。因此,網(wǎng)間進(jìn)程通信還要解決多重協(xié)議的識別問題。
????? 為此,TCP/IP協(xié)議為網(wǎng)間進(jìn)程通信問題建立了IP地址,端口,Socket(套接字)等概念。
???? (1) IP地址
?????????? IP地址是連入網(wǎng)絡(luò)中的機(jī)器的唯一識別地址。信息可以根據(jù)IP選擇路由方向,從而找到目的地機(jī)器。這就像 ? 郵遞員(路由器)根據(jù)你們家房子(目的機(jī)器)的地址(IP地址)遞送包裹(信息) ? 。
?
???? (2) 端口
?????????? 我們知道,一臺擁有IP地址的主機(jī)可以提供許多服 務(wù),比如web服務(wù)、FTP服務(wù)、SMTP服務(wù)等。對于不同的服務(wù)請求,主機(jī)需要調(diào)用不同的程序進(jìn)行處理。可是主機(jī)怎么知道是什么服務(wù)請求那?顯然僅僅知道IP地址是不夠的,因?yàn)镮P 地址與網(wǎng)絡(luò)服務(wù)的關(guān)系是一對多的關(guān)系。實(shí)際上是通過“IP地址+端口號”來區(qū)分不同的服務(wù)的。
????????? 端口實(shí)質(zhì)上是抽象的軟件結(jié)構(gòu)(不要理解成機(jī)器上的USB插槽),它包括一些數(shù)據(jù)結(jié)構(gòu)和I/O(基本輸入輸出)緩沖區(qū)。系統(tǒng)會為這些數(shù)據(jù)結(jié)構(gòu)和緩沖區(qū)指定一個唯一的端口號。不同的端口號對應(yīng)提供不同服務(wù)的程序。比如80號端口是HTTP端口,當(dāng)要申請主機(jī)的HTTP服務(wù)時,我們將申請信息發(fā)送到指定IP的80號端口的數(shù)據(jù)結(jié)構(gòu)內(nèi)。這時主機(jī)會監(jiān)聽到80號端口有服務(wù)請求,自動調(diào)用HTTP服務(wù)進(jìn)程進(jìn)行服務(wù)。
????????? ? 如果說IP地址是你家房子的地址,那么端口就是你家的門(這個房子確實(shí)門多了點(diǎn))。不同的訪客走不同的門,行賄的家伙一定要走后門(不排除小偷翻窗戶的可能) ? 。 當(dāng)你聽到后門有人敲門的時候,嘿嘿......
?
????? (3) Socket 套接字
?????? 有的時候,多個應(yīng)用程序可能同時需要向同一個接口發(fā)送數(shù)據(jù) ? ? ? 。為了區(qū)別不同的應(yīng)用程序進(jìn)程和連接 ? ,許多計(jì)算機(jī)操作系統(tǒng)為應(yīng)用程序與TCP/IP協(xié)議交互提供了稱為套接字(Socket)的接口。
????? ? 區(qū)分不同應(yīng)用程序進(jìn)程間的網(wǎng)絡(luò)通信和連接,主要有3個參數(shù):通信的目的IP地址、使用的傳輸層協(xié)議(TCP或UDP)和使用的端口號。Socket原意 是 “插座”。通過將這3個參數(shù)結(jié)合起來,與一個“插座”Socket綁定,應(yīng)用層就可以和傳輸層通過套接字接口,區(qū)分來自不同應(yīng)用程序進(jìn)程或網(wǎng)絡(luò)連接的通信,實(shí)現(xiàn)數(shù)據(jù)傳輸?shù)牟l(fā)服務(wù)。
?
?
Socket可以看成在兩個程序進(jìn)行通訊連接中的一個端點(diǎn),是連接應(yīng)用程序和網(wǎng)絡(luò)驅(qū)動程序的橋梁,Socket在應(yīng)用程序中創(chuàng)建,通過綁定與網(wǎng)絡(luò)驅(qū)動 建立關(guān)系。此后,應(yīng)用程序送給Socket的數(shù)據(jù),由Socket交網(wǎng)絡(luò)驅(qū)動程序向網(wǎng)絡(luò)上發(fā)送出去。計(jì)算機(jī)從網(wǎng)絡(luò)上收到與該Socket綁定IP地址和端 口號相關(guān)的數(shù)據(jù)后,由網(wǎng)絡(luò)驅(qū)動程序交給Socket,應(yīng)用程序便可從該Socket中提取接收到得數(shù)據(jù),網(wǎng)絡(luò)應(yīng)用程序就是這樣通過Socket進(jìn)行數(shù)據(jù)的 發(fā)送與接收的。
?
?
????? ? 了解了基于TCP/IP協(xié)議的網(wǎng)間進(jìn)程通信的部分概念之后,現(xiàn)在我想寫一個Java版的C-S通信程序。既然應(yīng)用程序需要通過"套接字"向網(wǎng)絡(luò)發(fā)出請求或者應(yīng)答網(wǎng)絡(luò)請求。我們自然要為客戶端和服務(wù)器端的程序創(chuàng)建自己的Socket。
?????? 還好,JDK中就有我們想要的東西——Socket和ServerSocket類。簡單介紹一下這兩個類:
??? ? Socket類用于客戶端,為建立網(wǎng)絡(luò)連接時使用的。在連接成功時,應(yīng)用程序兩端都會產(chǎn)生一個Socket實(shí)例,操作這個實(shí)例,完成所需的會話。
????? ServerSocket類用于服務(wù)器端,他可以創(chuàng)建綁定到特定端口的服務(wù)器套接字。當(dāng)監(jiān)聽到端口內(nèi)容時,他將創(chuàng)建一個用于鏈接的Socket對象。
????? 對于一個網(wǎng)絡(luò)連接來說,套接字是平等的,并沒有差別,不因?yàn)樵诜?wù)器端或在客戶端而產(chǎn)生不同級別。不管是Socket還是 ServerSocket它們的工作都是通過SocketImpl類及其子類完成的。
?
- //客戶端程序,用于向服務(wù)器端發(fā)送一句“hello?server!” ??
- import ?java.net.*;??
- import ?java.io.*;??
- public ? class ?Client{??
- ???? private ?String?ipTo= "172.16.129.13" ; //服務(wù)器端IP地址 ??
- ???? private ? int ?port= 8189 ; //需要通過的服務(wù)器端口號 ??
- ??????
- ???? public ? void ?hello(){??
- ???????? try {??
- ??????????????????????? //創(chuàng)建一個流套接字并將其連接到指定?IP?地址的指定端口號。? ??
- ????????????Socket?clientSocket= new ?Socket(ipTo,port);??
- ???????????? try {??
- ????????????????System.out.println( "success?connection...." );??
- ???????????????????????????????? //返回此套接字的輸出流 ??
- ????????????????OutputStream?os=clientSocket.getOutputStream();??
- ????????????????PrintWriter?pw= new ?PrintWriter(os, true );??
- ????????????????????pw.println( "hello?server!" );??
- ????????????}??
- ???????????? finally {??
- ????????????????clientSocket.close();??
- ????????????}??
- ????????} catch (IOException?e){??
- ????????????e.printStackTrace();??
- ????????}??
- ????}??
- ??
- ???? public ? static ? void ?main(String[]?args)??
- ????{??
- ????????Client?client= new ?Client();??
- ????????client.hello();??
- ????}??
- }??
- //服務(wù)器端程序,用于接受客戶端的信息 ??
- import ?java.net.*;??
- import ?java.io.*;??
- public ? class ?Server{??
- ???? private ? int ?lisenerPort= 8189 ; //監(jiān)聽端口 ??
- ??
- ???? private ? void ?lisener(){??
- ???????? try {??
- ?????????????????????? //創(chuàng)建服務(wù)器端套接字,用于綁定指定端口 ??
- ????????????ServerSocket?serverSocket= new ?ServerSocket(lisenerPort);??
- ?????????????????????? //監(jiān)聽綁定的端口,用于產(chǎn)生阻塞,直到接受到一個來自客戶端的有效連接,并且返回一個客戶端的Socket對象實(shí)例。 ??
- ????????????Socket?socket=serverSocket.accept();??
- ???????????? try {??
- ???????????????????????????????? //創(chuàng)建套接字輸入流 ??
- ????????????????InputStream?is=socket.getInputStream();??
- ????????????????BufferedReader?br= new ?BufferedReader( new ?InputStreamReader(is));??
- ???????????????????????????????? //服務(wù)器端顯示來自客戶端的問候 ??
- ????????????????System.out.println(br.readLine());??
- ????????????}??
- ???????????? finally {??
- ????????????????serverSocket.close();??
- ????????????}??
- ????????} catch (IOException?e)??
- ????????{??
- ????????????e.printStackTrace();??
- ????????}??
- ????}??
- ???? public ? static ? void ?main(String[]?args)??
- ????{??
- ????????Server?server= new ?Server();??
- ????????server.lisener();??
- ????}??
- ??
- }??
更多文章、技術(shù)交流、商務(wù)合作、聯(lián)系博主
微信掃碼或搜索:z360901061

微信掃一掃加我為好友
QQ號聯(lián)系: 360901061
您的支持是博主寫作最大的動力,如果您喜歡我的文章,感覺我的文章對您有幫助,請用微信掃描下面二維碼支持博主2元、5元、10元、20元等您想捐的金額吧,狠狠點(diǎn)擊下面給點(diǎn)支持吧,站長非常感激您!手機(jī)微信長按不能支付解決辦法:請將微信支付二維碼保存到相冊,切換到微信,然后點(diǎn)擊微信右上角掃一掃功能,選擇支付二維碼完成支付。
【本文對您有幫助就好】元
