日韩性视频-久久久蜜桃-www中文字幕-在线中文字幕av-亚洲欧美一区二区三区四区-撸久久-香蕉视频一区-久久无码精品丰满人妻-国产高潮av-激情福利社-日韩av网址大全-国产精品久久999-日本五十路在线-性欧美在线-久久99精品波多结衣一区-男女午夜免费视频-黑人极品ⅴideos精品欧美棵-人人妻人人澡人人爽精品欧美一区-日韩一区在线看-欧美a级在线免费观看

歡迎訪問(wèn) 生活随笔!

生活随笔

當(dāng)前位置: 首頁(yè) > 编程语言 > java >内容正文

java

java中no1_【Java】-- 网络编程のNo.1

發(fā)布時(shí)間:2025/3/15 java 19 豆豆
生活随笔 收集整理的這篇文章主要介紹了 java中no1_【Java】-- 网络编程のNo.1 小編覺(jué)得挺不錯(cuò)的,現(xiàn)在分享給大家,幫大家做個(gè)參考.

在現(xiàn)有的網(wǎng)絡(luò)中,網(wǎng)絡(luò)通訊的方式主要有兩種:

TCP(傳輸控制協(xié)議)方式

UDP(用戶數(shù)據(jù)報(bào)協(xié)議)方式

在網(wǎng)絡(luò)通訊中,TCP方式就類似于撥打電話,使用該種方式進(jìn)行網(wǎng)絡(luò)通訊時(shí),需要建立專門的虛擬連接,然后進(jìn)行可靠的數(shù)據(jù)傳輸,如果數(shù)據(jù)發(fā)送失敗,則客戶端會(huì)自動(dòng)重發(fā)該數(shù)據(jù)。

而UDP方式就類似于發(fā)送短信,使用這種方式進(jìn)行網(wǎng)絡(luò)通訊時(shí),不需要建立專門的虛擬連接,傳輸也不是很可靠,如果發(fā)送失敗則客戶端無(wú)法獲得。

這兩種傳輸方式都是實(shí)際的網(wǎng)絡(luò)編程中進(jìn)行使用,重要的數(shù)據(jù)一般使用TCP方式進(jìn)行數(shù)據(jù)傳輸,而大量的非核心數(shù)據(jù)則都通過(guò)UDP方式進(jìn)行傳遞,在一些程序中甚至結(jié)合使用這兩種方式進(jìn)行數(shù)據(jù)的傳遞。

由于TCP需要建立專用的虛擬連接以及確認(rèn)傳輸是否正確,所以使用TCP方式的速度稍微慢一些,而且傳輸時(shí)產(chǎn)生的數(shù)據(jù)量要比UDP稍微大一些。

無(wú)論使用TCP方式還是UDP方式進(jìn)行網(wǎng)絡(luò)通訊,網(wǎng)絡(luò)編程都是由客戶端和服務(wù)器端組成當(dāng)然,B/S結(jié)構(gòu)的編程中只需要實(shí)現(xiàn)服務(wù)器端即可。所以,下面介紹網(wǎng)絡(luò)編程的步驟時(shí),均以C/S結(jié)構(gòu)為基礎(chǔ)進(jìn)行介紹。

網(wǎng)絡(luò)編程技術(shù)

1、客戶端網(wǎng)絡(luò)編程步驟

客戶端(Client)是指網(wǎng)絡(luò)編程中首先發(fā)起連接的程序,客戶端一般實(shí)現(xiàn)程序界面和基本邏輯實(shí)現(xiàn),在進(jìn)行實(shí)際的客戶端編程時(shí),無(wú)論客戶端復(fù)雜還是簡(jiǎn)單,以及客戶端實(shí)現(xiàn)的方式,客戶端的編程主要由三個(gè)步驟實(shí)現(xiàn):

建立網(wǎng)絡(luò)連接

客戶端網(wǎng)絡(luò)編程的第一步都是建立網(wǎng)絡(luò)連接。在建立網(wǎng)絡(luò)連接時(shí)需要指定連接到的服務(wù)器的IP地址和端口號(hào),建立完成以后,會(huì)形成一條虛擬的連接,后續(xù)的操作就可以通過(guò)該連接實(shí)現(xiàn)數(shù)據(jù)交換了。

交換數(shù)據(jù)

連接建立以后,就可以通過(guò)這個(gè)連接交換數(shù)據(jù)了。交換數(shù)據(jù)嚴(yán)格按照請(qǐng)求響應(yīng)模型進(jìn)行,由客戶端發(fā)送一個(gè)請(qǐng)求數(shù)據(jù)到服務(wù)器,服務(wù)器反饋一個(gè)響應(yīng)數(shù)據(jù)給客戶端,如果客戶端不發(fā)送請(qǐng)求則服務(wù)器端就不響應(yīng)。根據(jù)邏輯需要,可以多次交換數(shù)據(jù),但是還是必須遵循請(qǐng)求響應(yīng)模型。

關(guān)閉網(wǎng)絡(luò)連接

在數(shù)據(jù)交換完成以后,關(guān)閉網(wǎng)絡(luò)連接,釋放程序占用的端口、內(nèi)存等系統(tǒng)資源,結(jié)束網(wǎng)絡(luò)編程。

在實(shí)際實(shí)現(xiàn)時(shí),步驟2會(huì)出現(xiàn)重復(fù),在進(jìn)行代碼組織時(shí),由于網(wǎng)絡(luò)編程是比較耗時(shí)的操作,所以一般開啟專門的現(xiàn)場(chǎng)進(jìn)行網(wǎng)絡(luò)通訊。

2、服務(wù)器端網(wǎng)絡(luò)編程步驟

服務(wù)器端(Server)是指在網(wǎng)絡(luò)編程中被動(dòng)等待連接的程序,服務(wù)器端一般實(shí)現(xiàn)程序的核心邏輯以及數(shù)據(jù)存儲(chǔ)等核心功能。服務(wù)器端的編程步驟和客戶端不同,是由四個(gè)步驟實(shí)現(xiàn),依次是:

監(jiān)聽(tīng)端口

服務(wù)器端屬于被動(dòng)等待連接,所以服務(wù)器端啟動(dòng)以后,不需要發(fā)起連接,而只需要監(jiān)聽(tīng)本地計(jì)算機(jī)的某個(gè)固定端口即可。

這個(gè)端口就是服務(wù)器端開放給客戶端的端口,服務(wù)器端程序運(yùn)行的本地計(jì)算機(jī)的IP地址就是服務(wù)器端程序的IP地址。

獲得連接

當(dāng)客戶端連接到服務(wù)器端時(shí),服務(wù)器端就可以獲得一個(gè)連接,這個(gè)連接包含客戶端的信息,例如客戶端IP地址等等,服務(wù)器端和客戶端也通過(guò)該連接進(jìn)行數(shù)據(jù)交換。

一般在服務(wù)器端編程中,當(dāng)獲得連接時(shí),需要開啟專門的線程處理該連接,每個(gè)連接都由獨(dú)立的線程實(shí)現(xiàn)。

交換數(shù)據(jù)

服務(wù)器端通過(guò)獲得的連接進(jìn)行數(shù)據(jù)交換。服務(wù)器端的數(shù)據(jù)交換步驟是首先接收客戶端發(fā)送過(guò)來(lái)的數(shù)據(jù),然后進(jìn)行邏輯處理,再把處理以后的結(jié)果數(shù)據(jù)發(fā)送給客戶端。簡(jiǎn)單來(lái)說(shuō),就是先接收再發(fā)送,這個(gè)和客戶端的數(shù)據(jù)交換數(shù)序不同。

其實(shí),服務(wù)器端獲得的連接和客戶端連接是一樣的,只是數(shù)據(jù)交換的步驟不同。

當(dāng)然,服務(wù)器端的數(shù)據(jù)交換也是可以多次進(jìn)行的。

在數(shù)據(jù)交換完成以后,關(guān)閉和客戶端的連接。

關(guān)閉連接

當(dāng)服務(wù)器程序關(guān)閉時(shí),需要關(guān)閉服務(wù)器端,通過(guò)關(guān)閉服務(wù)器端使得服務(wù)器監(jiān)聽(tīng)的端口以及占用的內(nèi)存可以釋放出來(lái),實(shí)現(xiàn)了連接的關(guān)閉。

TCP方式是需要建立連接的,對(duì)于服務(wù)器端的壓力比較大,而UDP是不需要建立連接的,對(duì)于服務(wù)器端的壓力比較小罷了。

Java網(wǎng)絡(luò)編程技術(shù)

和網(wǎng)絡(luò)編程有關(guān)的基本API位于java.net包中,該包中包含了基本的網(wǎng)絡(luò)編程實(shí)現(xiàn),該包是網(wǎng)絡(luò)編程的基礎(chǔ)。該包中既包含基礎(chǔ)的網(wǎng)絡(luò)編程類,也包含封裝后的專門處理WEB相關(guān)的處理類。

InetAddress類

該類的功能是代表一個(gè)IP地址,并且將IP地址和域名相關(guān)的操作方法包含在該類的內(nèi)部。

先來(lái)個(gè)Demo

publicstaticvoidmain(String[]?args)throwsIOException?{

try{

//使用域名創(chuàng)建對(duì)象

InetAddress?address=InetAddress.getByName("www.163.com");

System.out.println(address);

//使用ip創(chuàng)建對(duì)象

InetAddress?address2=InetAddress.getByName("222.184.115.167");

System.out.println(address2);

//獲得本機(jī)地址對(duì)象

InetAddress?address3?=?InetAddress.getLocalHost();

System.out.println(address3);

//獲得對(duì)象中存儲(chǔ)的域名

System.out.println("域名:"+address3.getHostName());

//獲得對(duì)象中存儲(chǔ)的ip地址

System.out.println("IP地址:"+address3.getHostAddress());

}?catch(Exception?e)?{

//?TODO:?handle?exception

}

}

由于該代碼中包含一個(gè)互聯(lián)網(wǎng)的網(wǎng)址,所以運(yùn)行該程序時(shí)需要聯(lián)網(wǎng),否則將產(chǎn)生異常。

在后續(xù)的使用中,經(jīng)常包含需要使用InetAddress對(duì)象代表IP地址的構(gòu)造方法,當(dāng)然,該類的使用不是必須的,也可以使用字符串來(lái)代表IP地址進(jìn)行實(shí)現(xiàn)。

TCP編程

在Java語(yǔ)言中,對(duì)于TCP方式的網(wǎng)絡(luò)編程提供了良好的支持,在實(shí)際實(shí)現(xiàn)時(shí),以java.net.Socket類代表客戶端連接,以java.net.ServerSocket類代表服務(wù)器端連接。在進(jìn)行網(wǎng)絡(luò)編程時(shí),底層網(wǎng)絡(luò)通訊的細(xì)節(jié)已經(jīng)實(shí)現(xiàn)了比較高的封裝,所以在程序員實(shí)際編程時(shí),只需要指定IP地址和端口號(hào)碼就可以建立連接了。正是由于這種高度的封裝,一方面簡(jiǎn)化了Java語(yǔ)言網(wǎng)絡(luò)編程的難度,另外也使得使用Java語(yǔ)言進(jìn)行網(wǎng)絡(luò)編程時(shí)無(wú)法深入到網(wǎng)絡(luò)的底層,所以使用Java語(yǔ)言進(jìn)行網(wǎng)絡(luò)底層系統(tǒng)編程很困難,具體點(diǎn)說(shuō),Java語(yǔ)言無(wú)法實(shí)現(xiàn)底層的網(wǎng)絡(luò)嗅探以及獲得IP包結(jié)構(gòu)等信息。但是由于Java語(yǔ)言的網(wǎng)絡(luò)編程比較簡(jiǎn)單,所以還是獲得了廣泛的使用。

在使用TCP方式進(jìn)行網(wǎng)絡(luò)編程時(shí),需要按照前面介紹的網(wǎng)絡(luò)編程的步驟進(jìn)行,下面分別介紹一下在Java語(yǔ)言中客戶端和服務(wù)器端的實(shí)現(xiàn)步驟。

在客戶端網(wǎng)絡(luò)編程中,首先需要建立連接,在Java API中以java.net.Socket類的對(duì)象代表網(wǎng)絡(luò)連接,所以建立客戶端網(wǎng)絡(luò)連接,也就是創(chuàng)建Socket類型的對(duì)象,該對(duì)象代表網(wǎng)絡(luò)連接

//?socket1實(shí)現(xiàn)的是連接到IP地址是192.168.1.103的計(jì)算機(jī)的10000號(hào)端口

Socket?socket1?=?newSocket("192.168.1.103",10000);

//?socket2實(shí)現(xiàn)的是連接到域名是www.sohu.com的計(jì)算機(jī)的80號(hào)端口

Socket?socket2?=?newSocket("www.sohu.com",80);

底層網(wǎng)絡(luò)如何實(shí)現(xiàn)建立連接,對(duì)于程序員來(lái)說(shuō)是完全透明的。如果建立連接時(shí),本機(jī)網(wǎng)絡(luò)不通,或服務(wù)器端程序未開啟,則會(huì)拋出異常。

連接一旦建立,則完成了客戶端編程的第一步,緊接著的步驟就是按照“請(qǐng)求-響應(yīng)”模型進(jìn)行網(wǎng)絡(luò)數(shù)據(jù)交換,在Java語(yǔ)言中,數(shù)據(jù)傳輸功能由Java IO實(shí)現(xiàn),也就是說(shuō)只需要從連接中獲得輸入流和輸出流即可,然后將需要發(fā)送的數(shù)據(jù)寫入連接對(duì)象的輸出流中,在發(fā)送完成以后從輸入流中讀取數(shù)據(jù)即可。

//獲得輸出流

OutputStream?outputStream?=?socket1.getOutputStream();

//獲得輸入流

InputStream?inputStream=socket1.getInputStream();

這里獲得的只是最基本的輸出流和輸入流對(duì)象,還可以根據(jù)前面學(xué)習(xí)到的IO知識(shí),使用流的嵌套將這些獲得到的基本流對(duì)象轉(zhuǎn)換成需要的裝飾流對(duì)象,從而方便數(shù)據(jù)的操作。

最后當(dāng)數(shù)據(jù)交換完成以后,關(guān)閉網(wǎng)絡(luò)連接,釋放網(wǎng)絡(luò)連接占用的系統(tǒng)端口和內(nèi)存等資源,完成網(wǎng)絡(luò)操作,示例代碼如下:

socket1.close();

以上就是最基本的網(wǎng)絡(luò)編程功能介紹。

接下來(lái)寫個(gè)客戶端的Demo,程序在客戶端發(fā)送字符串到服務(wù)器,并將服務(wù)器端的反饋顯示到控制臺(tái),數(shù)據(jù)交換只進(jìn)行一次,當(dāng)數(shù)據(jù)交換進(jìn)行完成以后關(guān)閉網(wǎng)絡(luò)連接,程序結(jié)束。

先來(lái)客戶端的代碼

importjava.io.InputStream;

importjava.io.OutputStream;

importjava.net.Socket;

publicclassClient?{

publicstaticvoidmain(String[]?args)?{

Socket?socket?=?null;

InputStream?is?=?null;

OutputStream?os?=?null;

try{

String?msg?=?"Hello";

String?ip?=?"localhost";

intport?=9898;

//?建立連接

socket?=?newSocket(ip,?port);

//?發(fā)送數(shù)據(jù)

os?=?socket.getOutputStream();

os.write(msg.getBytes());

//?接收數(shù)據(jù)

is?=?socket.getInputStream();

byteb[]=newbyte[1024];

intn?=is.read(b);

System.out.println(newString(b,0,n));

}?catch(Exception?e)?{

//?TODO:?handle?exception

e.printStackTrace();

}?finally{

try{

//關(guān)閉連接和流

is.close();

os.close();

socket.close();

}?catch(Exception?e2)?{

//?TODO:?handle?exception

e2.printStackTrace();

}

}

}

}

代碼中建服務(wù)器端的代碼:

publicclassServer?{

publicstaticvoidmain(String[]?args)?{

ServerSocket?serverSocket=null;

Socket?socket=null;

InputStream?is?=null;

OutputStream?os?=null;

try{

serverSocket?=?newServerSocket(9898);

socket?=?serverSocket.accept();

is?=?socket.getInputStream();

byteb[]?=newbyte[1024];

intn?=?is.read(b);

System.out.println("客戶端發(fā)送了:"+newString(b,0,n));

os?=?socket.getOutputStream();

os.write("接收成功!".getBytes());

}?catch(Exception?e)?{

//?TODO:?handle?exception

e.printStackTrace();

}finally{

try{

is.close();

os.close();

socket.close();

serverSocket.close();

}?catch(Exception?e2)?{

//?TODO:?handle?exception

}

}

}

}

先運(yùn)行服務(wù)器端,然后運(yùn)行客戶端,服務(wù)器接收到數(shù)據(jù)將數(shù)據(jù)打印出來(lái)之后再返回?cái)?shù)據(jù)到客戶端,客戶端打印出來(lái)

在該示例代碼中建立了一個(gè)監(jiān)聽(tīng)當(dāng)前計(jì)算機(jī)9898號(hào)端口的服務(wù)器端Socket連接,然后獲得客戶端發(fā)送過(guò)來(lái)的連接,如果有連接到達(dá)時(shí),讀取連接中發(fā)送過(guò)來(lái)的內(nèi)容,并將發(fā)送的內(nèi)容在控制臺(tái)進(jìn)行輸出,輸出完成以后將客戶端發(fā)送的內(nèi)容再反饋給客戶端。最后關(guān)閉流和連接對(duì)象,結(jié)束程序。

在服務(wù)器端程序編程中,由于服務(wù)器端實(shí)現(xiàn)的是被動(dòng)等待連接,所以服務(wù)器端編程的第一個(gè)步驟是監(jiān)聽(tīng)端口,也就是監(jiān)聽(tīng)是否有客戶端連接到達(dá)。實(shí)現(xiàn)服務(wù)器端監(jiān)聽(tīng)的代碼為:

//?該代碼實(shí)現(xiàn)的功能是監(jiān)聽(tīng)當(dāng)前計(jì)算機(jī)的9898號(hào)端口,如果在執(zhí)行該代碼時(shí),

//?10000號(hào)端口已經(jīng)被別的程序占用,那么將拋出異常。否則將實(shí)現(xiàn)監(jiān)聽(tīng)。

serverSocket?=?newServerSocket(9898);

服務(wù)器端編程的第二個(gè)步驟是獲得連接。該步驟的作用是當(dāng)有客戶端連接到達(dá)時(shí),建立一個(gè)和客戶端連接對(duì)應(yīng)的Socket連 接對(duì)象,從而釋放客戶端連接對(duì)于服務(wù)器端端口的占用。通過(guò)獲得連接,使得客戶端的連接在服務(wù)器端獲得了保持,另外使得服務(wù)器端的端口釋放出來(lái),可以繼續(xù)等待其它的客戶端連接。 實(shí)現(xiàn)獲得連接的代碼是:

socket?=?serverSocket.accept();

該代碼實(shí)現(xiàn)的功能是獲得當(dāng)前連接到服務(wù)器端的客戶端連接。需要說(shuō)明的是accept和前面IO部分介紹的read方法一樣,都是一個(gè)阻塞方法,也就是當(dāng)無(wú)連接時(shí),該方法將阻塞程序的執(zhí)行,直到連接到達(dá)時(shí)才執(zhí)行該行代碼。另外獲得的連接會(huì)在服務(wù)器端的該端口注冊(cè),這樣以后就可以通過(guò)在服務(wù)器端的注冊(cè)信息直接通信,而注冊(cè)以后服務(wù)器端的端口就被釋放出來(lái),又可以繼續(xù)接受其它的連接了。

連接獲得以后,后續(xù)的編程就和客戶端的網(wǎng)絡(luò)編程類似了,這里獲得的Socket類型的連接就和客戶端的網(wǎng)絡(luò)連接一樣了,只是服務(wù)器端需要首先讀取發(fā)送過(guò)來(lái)的數(shù)據(jù),然后進(jìn)行邏輯處理以后再發(fā)送給客戶端,也就是交換數(shù)據(jù)的順序和客戶端交換數(shù)據(jù)的步驟剛好相反。這部分的內(nèi)容和客戶端很類似。

--------------------------

上面這個(gè)示例只是演示了網(wǎng)絡(luò)編程的基本步驟以及各個(gè)功能方法的基本使用,只是為網(wǎng)絡(luò)編程打下了一個(gè)基礎(chǔ),下面將就幾個(gè)問(wèn)題來(lái)深入介紹網(wǎng)絡(luò)編程深層次的一些知識(shí)。

1.如何復(fù)用Socket連接?

撥通一次電話以后多次對(duì)話,這就是復(fù)用客戶端連接。

建立連接以后,將數(shù)據(jù)交換的邏輯寫到一個(gè)循環(huán)中,只要循環(huán)不結(jié)束則連接就不會(huì)被關(guān)閉,按照這種思路,可以改造一下上面的代碼,讓該程序可以在建立連接一次以后,發(fā)送三次數(shù)據(jù),當(dāng)然這里的次數(shù)也可以是多次

現(xiàn)在看下新的服務(wù)器代碼和客戶端代碼:

importjava.io.InputStream;

importjava.io.OutputStream;

importjava.net.ServerSocket;

importjava.net.Socket;

/**

*?服務(wù)器代碼

*?*/

publicclassServer?{

publicstaticvoidmain(String[]?args)?{

ServerSocket?serverSocket?=?null;

Socket?socket?=?null;

InputStream?is?=?null;

OutputStream?os?=?null;

try{

serverSocket?=?newServerSocket(9898);

socket?=?serverSocket.accept();

is?=?socket.getInputStream();

os?=?socket.getOutputStream();

byteb[]?=newbyte[1024];

for(inti?=0;?i?<3;?i++)?{

intn?=?is.read(b);

os.write(("客戶端發(fā)送的內(nèi)容:"+newString(b,0,?n)).getBytes());

}

}?catch(Exception?e)?{

//?TODO:?handle?exception

e.printStackTrace();

}?finally{

try{

is.close();

os.close();

socket.close();

serverSocket.close();

}?catch(Exception?e2)?{

//?TODO:?handle?exception

}

}

}

}

再看下新的客戶端代碼:

importjava.io.InputStream;

importjava.io.OutputStream;

importjava.net.Socket;

/**

*?客戶端代碼

*?*/

publicclassClient?{

publicstaticvoidmain(String[]?args)?{

Socket?socket?=?null;

InputStream?is?=?null;

OutputStream?os?=?null;

try{

String?msg[]?=?{?"one","two","three"};

String?ip?=?"localhost";

intport?=9898;

//?建立連接

socket?=?newSocket(ip,?port);

//?發(fā)送數(shù)據(jù)

os?=?socket.getOutputStream();

//?接收數(shù)據(jù)

is?=?socket.getInputStream();

byteb[]?=newbyte[1024];

for(inti?=0;?i?

os.write(msg[i].getBytes());

intn?=?is.read(b);

System.out.println(newString(b,0,?n));

}

}?catch(Exception?e)?{

//?TODO:?handle?exception

e.printStackTrace();

}?finally{

try{

//?關(guān)閉連接和流

is.close();

os.close();

socket.close();

}?catch(Exception?e2)?{

//?TODO:?handle?exception

e2.printStackTrace();

}

}

}

}

上面的代碼雖然比較簡(jiǎn)單,但是通用性比較差。

在該程序中,比較明顯的體現(xiàn)出了“請(qǐng)求-響應(yīng)”模型,也就是在客戶端發(fā)起連接以后,首先發(fā)送字符串“First”給服務(wù)器端,服務(wù)器端輸出客戶端發(fā)送的內(nèi)容“First”,然后將客戶端發(fā)送的內(nèi)容再反饋給客戶端,這樣客戶端也輸出服務(wù)器反饋“First”,這樣就完成了客戶端和服務(wù)器端的一次對(duì)話

三次會(huì)話的過(guò)程一樣,在這個(gè)過(guò)程中,每次都是客戶端程序首先發(fā)送數(shù)據(jù)給服務(wù)器端,服務(wù)器接收數(shù)據(jù)以后,將結(jié)果反饋給客戶端,客戶端接收到服務(wù)器端的反饋,從而完成一次通訊過(guò)程。

2、如何使服務(wù)器端支持多個(gè)客戶端同時(shí)工作?

一個(gè)服務(wù)器端一般都需要同時(shí)為多個(gè)客戶端提供通訊,如果需要同時(shí)支持多個(gè)客戶端,則必須使用前面介紹的線程的概念。簡(jiǎn)單來(lái)說(shuō),也就是當(dāng)服務(wù)器端接收到一個(gè)連接時(shí),啟動(dòng)一個(gè)專門的線程處理和該客戶端的通訊。

改造之后的服務(wù)器代碼,可以接收多個(gè)客戶端的數(shù)據(jù)。

在該示例代碼中,實(shí)現(xiàn)了一個(gè)while形式的死循環(huán),由于accept方法是阻塞方法,所以當(dāng)客戶端連接未到達(dá)時(shí),將阻塞該程序的執(zhí)行,當(dāng)客戶端到達(dá)時(shí)接收該連接,并啟動(dòng)一個(gè)新的LogicThread線程處理該連接,然后按照循環(huán)的執(zhí)行流程,繼續(xù)等待下一個(gè)客戶端連接。這樣當(dāng)任何一個(gè)客戶端連接到達(dá)時(shí),都開啟一個(gè)專門的線程處理,通過(guò)多個(gè)線程支持多個(gè)客戶端同時(shí)處理。

/**

*?支持多客戶端的服務(wù)器代碼

*?*/

publicclassServer?{

publicstaticvoidmain(String[]?args)?{

ServerSocket?serverSocket?=?null;

Socket?socket?=?null;

try{

serverSocket?=?newServerSocket(9898);

while(true)?{

socket?=?serverSocket.accept();

//?啟動(dòng)線程

//?實(shí)現(xiàn)接收客戶端連接,然后開啟專門的邏輯線程處理該連接,

//?LogicThread類實(shí)現(xiàn)對(duì)于一個(gè)客戶端連接的邏輯處理,將處理的邏輯放置在該類的run方法中。

newLogicThread(socket);

}

}?catch(Exception?e)?{

//?TODO:?handle?exception

e.printStackTrace();

}?finally{

try{

socket.close();

serverSocket.close();

}?catch(Exception?e2)?{

//?TODO:?handle?exception

}

}

}

staticclassLogicThreadextendsThread?{

Socket?socket?=?null;

publicLogicThread(Socket?socket)?{

this.socket?=?socket;

start();

}

@Override

publicvoidrun()?{

byteb[]?=newbyte[1024];

InputStream?is?=?null;

OutputStream?os?=?null;

try{

is?=?socket.getInputStream();

os?=?socket.getOutputStream();

intn?=?is.read(b);

os.write(("客戶端發(fā)送的內(nèi)容:"+newString(b,0,?n)).getBytes());

}?catch(Exception?e)?{

//?TODO:?handle?exception

e.printStackTrace();

}?finally{

try{

is.close();

os.close();

socket.close();

}?catch(Exception?e2)?{

//?TODO:?handle?exception

}

}

}

}

}

這里的示例還只是基礎(chǔ)的服務(wù)器端實(shí)現(xiàn),在實(shí)際的服務(wù)器端實(shí)現(xiàn)中,由于硬件和端口數(shù)的限制,所以不能無(wú)限制的創(chuàng)建線程對(duì)象,而且頻繁的創(chuàng)建線程對(duì)象效率也比較低,所以程序中都實(shí)現(xiàn)了線程池來(lái)提高程序的執(zhí)行效率。

這里簡(jiǎn)單介紹一下線程池的概念,線程池(Thread pool)是池技術(shù)的一種,就是在程序啟動(dòng)時(shí)首先把需要個(gè)數(shù)的線程對(duì)象創(chuàng)建好,例如創(chuàng)建5000個(gè)線程對(duì)象,然后當(dāng)客戶端連接到達(dá)時(shí)從池中取出一個(gè)已經(jīng)創(chuàng)建完成的線程對(duì)象使用即可。當(dāng)客戶端連接關(guān)閉以后,將該線程對(duì)象重新放入到線程池中供其它的客戶端重復(fù)使用,這樣可以提高程序的執(zhí)行速度,優(yōu)化程序?qū)τ趦?nèi)存的占用等。

關(guān)于基礎(chǔ)的TCP方式的網(wǎng)絡(luò)編程就介紹這么多,下面一章介紹UDP方式的網(wǎng)絡(luò)編程在Java語(yǔ)言中的實(shí)現(xiàn)。

總結(jié)

以上是生活随笔為你收集整理的java中no1_【Java】-- 网络编程のNo.1的全部?jī)?nèi)容,希望文章能夠幫你解決所遇到的問(wèn)題。

如果覺(jué)得生活随笔網(wǎng)站內(nèi)容還不錯(cuò),歡迎將生活随笔推薦給好友。

主站蜘蛛池模板: 亚洲日本韩国在线 | 色眯眯视频 | 性――交――性――乱睡觉 | 午夜久久一区 | 日韩中文字幕精品视频 | 中文字幕永久在线观看 | 久久精品国产电影 | 在线免费观看国产视频 | 久久精品国产亚洲av蜜臀色欲 | 亚洲精品国产精品国自 | 欧美激情视频一区二区三区 | 国产探花在线精品一区二区 | 久久人人爽爽 | 尤物在线观看 | 久久久久99精品成人片三人毛片 | 亚洲精品一区三区三区在线观看 | 岛国精品在线播放 | 午夜综合| 最近中文字幕mv免费高清在线 | 欧美a级在线观看 | 乱h伦h女h在线视频 99999视频 | 91在线观看免费视频 | 国产一二三在线视频 | 成人综合精品 | 好邻居韩国剧在线观看 | 国产精品九九视频 | 51吃瓜网今日 | 久久精精品久久久久噜噜 | 亚洲一区二区三区色 | 国产日韩精品在线 | 日本大尺度做爰呻吟 | 狠狠躁18三区二区一区 | 在线观看成人一区 | 夫妻毛片 | www.人人干| www午夜| 日本成人动漫在线观看 | 天天射干| 亚洲天堂视频网站 | 久久人人爽人人爽人人 | www九色 | 性爱视频日本 | 少妇视频一区二区三区 | 欧美一区二区三区四区五区六区 | 国产理论在线 | 韩日视频一区 | 最近中文字幕av | 日本欧美中文字幕 | 中文字幕乱码在线观看 | 久久99草| 欧美精品一区二区性色a+v | 国产区视频在线观看 | 97久久久 | 99久99| 成人动作片 | 欧美国产一区二区 | 好色先生tv官网 | 国产激情精品一区二区三区 | 成人夜视频 | 另类在线视频 | 蜜臀av性久久久久蜜臀aⅴ四虎 | 69av网 | 插插看| 97se亚洲综合 | 国产二区精品视频 | 亚洲欧洲av | 在线天堂6 | 中文在线a∨在线 | 九九黄色 | 亚州综合网| 韩国黄色网 | 影院一区 | 两性视频久久 | 长篇乱肉合集乱500小说日本 | 欧美浓毛大泬视频 | 黄色网址视频 | 亚洲性网站| 野花国产精品入口 | 国产精品国产精品国产专区不卡 | 国产麻豆精品一区二区 | 亚洲熟妇中文字幕五十中出 | 日本美女日批视频 | 日韩成人精品一区 | 看国产一级片 | 免费高清视频一区二区三区 | 欧美大片一区二区三区 | 中文字幕 视频一区 | 久久av一区二区三区漫画 | 久久99久久99精品 | 国产精品一级片 | 婷婷五月综合缴情在线视频 | 亚洲精品88 | 久久成人毛片 | 久久黄色一级片 | 欧美va天堂 | 最近中文字幕第一页 | 亚洲精品乱码久久久久久蜜桃欧美 | 91精品国产乱码久久 | 一区二区在线观看免费 |