Java網(wǎng)絡(luò)編程三要素及通信程序詳解
1 網(wǎng)絡(luò)編程入門
1.1 網(wǎng)絡(luò)編程概述
- 計(jì)算機(jī)網(wǎng)絡(luò):是指將地理位置不同的具有獨(dú)立功能的多臺(tái)計(jì)算機(jī)及 其外部設(shè)備,通過(guò)通信線路連接起來(lái),在網(wǎng)絡(luò)操作系統(tǒng),網(wǎng)絡(luò)管理軟件及網(wǎng)絡(luò)通信協(xié)議的管理和協(xié)調(diào)下,實(shí)現(xiàn)資源共享和信息傳遞的計(jì)算機(jī)系統(tǒng)

- 網(wǎng)絡(luò)編程:在網(wǎng)絡(luò)通信協(xié)議下,實(shí)現(xiàn)網(wǎng)絡(luò)互連的不同計(jì)算機(jī)上運(yùn)行的程序間可以進(jìn)行數(shù)據(jù)交換
1.2 網(wǎng)絡(luò)編程三要素
- IP地址
要想讓網(wǎng)絡(luò)中的計(jì)算機(jī)能夠 互相通信,必須為每臺(tái)計(jì)算機(jī)指定一個(gè)標(biāo)識(shí)號(hào), 通過(guò)這個(gè)標(biāo)識(shí)號(hào)來(lái)指定要接收數(shù)據(jù)的計(jì)算機(jī)和識(shí)別發(fā)送的計(jì)算機(jī),而IP地址就是這個(gè)標(biāo)識(shí)號(hào)。也就是設(shè)備的標(biāo)識(shí)
- 端口
網(wǎng)絡(luò)的通信, 本質(zhì)上是兩個(gè)應(yīng)用程序的通信。每臺(tái)計(jì)算機(jī)都有很多的應(yīng)用程序,那么在網(wǎng)絡(luò)通信時(shí),如何區(qū)分這些應(yīng)用程序呢?如果說(shuō)IP地址可以唯一標(biāo)識(shí)網(wǎng)絡(luò)中的設(shè)備 ,那么端口號(hào)就可以唯一標(biāo)識(shí)設(shè)備中的應(yīng)用程序了。也就是應(yīng)用程序的標(biāo)識(shí)
- 協(xié)議
通過(guò)計(jì)算機(jī)網(wǎng)絡(luò)可以使多 臺(tái)計(jì)算機(jī)實(shí)現(xiàn)連接,位于同一個(gè)網(wǎng)絡(luò)中的計(jì)算機(jī)在進(jìn)行連接和通信時(shí)需要遵守-定的規(guī)則,這就好比在道路中行駛的汽車-定要遵守交通規(guī)則一 樣。在計(jì)算機(jī)網(wǎng)絡(luò)中,這些連接和通信的規(guī)則被稱為網(wǎng)絡(luò)通信協(xié)議,它對(duì)數(shù)據(jù)的傳輸格式、傳輸速率、傳輸步驟等做了統(tǒng)一規(guī)定, 通信雙方必須同時(shí)遵守才能完成數(shù)據(jù)交換。常見(jiàn)的協(xié)議有UDP協(xié)議和TCP協(xié)議
1.3 IP地址
- IP地址:是網(wǎng)絡(luò)中設(shè)備的唯一標(biāo)識(shí)
- IP地址分為兩大類
- IPv4:是給每個(gè)連接在網(wǎng)絡(luò)上的主機(jī)分配一個(gè)32bit地址。 按照TCP/IP規(guī)定,IP地址用二進(jìn)制來(lái)表示, 每個(gè)P地址長(zhǎng)32bit,也就是4個(gè)字節(jié)。例如一個(gè)采用I進(jìn)制形式的IP地址是11000000 101010000000001 01000010" ,這么長(zhǎng)的地址,處理起來(lái)也太費(fèi)勁了。為了方便使用,IP地址經(jīng)常被寫(xiě)成+進(jìn)制的形式,中間使用符號(hào)"分隔不同的字節(jié)。于是,. 上面的IP地址可以表示為"192168. 1.66" . IP地址的這種表示法叫做"盼+進(jìn)制表示法”, 這顯然比1和0容易記憶得多
- IPv6:由于互聯(lián)網(wǎng)的蓬勃發(fā)展, IP地址的需求量愈來(lái)愈大,但是網(wǎng)絡(luò)地址資源有限,使得IP的分配越發(fā)緊張。為了擴(kuò)大地址空間,通過(guò)IPv6重新定義地址空間,采用128位地址長(zhǎng)度,每16個(gè)字節(jié)-組,分成8組十六進(jìn)制數(shù),這樣就解決了網(wǎng)絡(luò)地址資源數(shù)量不夠的問(wèn)題
- 常用命令:
- ipconfig: 查看本機(jī)P地址ping
- IP地址:檢查網(wǎng)絡(luò)是否連通
- 特殊IP地址127.0.0.1:是回送地址,可以代表本機(jī)地址,一般用來(lái)測(cè)試使用
1.4 InetAddress的使用
- 為了方便我們對(duì)IP地址的獲取和操作, Java提供了一個(gè)類InetAddress供我們使用
- InetAddress:此類表示Internet協(xié)議(IP) 地址
- 導(dǎo)包:
import java.net.InetAddress
| 方法名 | 說(shuō)明 |
| static InetAddress getByName(String host) | 確定主機(jī)名稱的IP地址。 主機(jī)名稱可以是機(jī)器名稱,也可以是IP地址 |
| String getHostName() | 獲取此IP地址的主機(jī)名 |
| String getHostAddress() | 返回文本顯示中的IP地址字符串 |
范例
package test;
import java.net.InetAddress;
import java.net.UnknownHostException;
public class Demo {
public static void main(String[] args) throws UnknownHostException {
//1,static InetAddress getByName(String host) 確定主機(jī)名稱的IP地址。 主機(jī)名稱可以是機(jī)器名稱,也可以是IP地址
// InetAddress address = InetAddress.getByName("YM");
InetAddress address = InetAddress.getByName("192.168.128.1"); //推薦使用
System.out.println(address); //YM/192.168.128.1
//2,String getHostName() 獲取此IP地址的主機(jī)名
String hostName = address.getHostName();
System.out.println(hostName); //YM
//3,String getHostAddress() 返回文本顯示中的IP地址字符串
String hostAddress = address.getHostAddress();
System.out.println(hostAddress); //192.168.128.1
}
}1.5 端口
- 端口:設(shè)備上應(yīng)用程序的唯一標(biāo)識(shí)
- 端口號(hào):用兩個(gè)字節(jié)表示的整數(shù),它的取值范圍是0~65535。其中, 0~ 1023之間的端口號(hào)用于些知名的網(wǎng)絡(luò)服務(wù)和應(yīng)用,普通的應(yīng)用程序需要使用1024以上的端口號(hào)。如果端口號(hào)被另外一個(gè)服務(wù)或應(yīng)用所占用,會(huì)導(dǎo)致當(dāng)前程序啟動(dòng)失敗
1.6 協(xié)議
- 協(xié)議:計(jì)算機(jī)網(wǎng)絡(luò)中,連接和通信的規(guī)則被稱為網(wǎng)絡(luò)通信協(xié)議
UDP協(xié)議
- 用戶數(shù)據(jù)報(bào)協(xié)議(User Datagram Protocol)
- UDP是無(wú)連接通信協(xié)議, 即在數(shù)據(jù)傳輸時(shí),數(shù)據(jù)的發(fā)送端和接收端不建立邏輯連接。簡(jiǎn)單來(lái)說(shuō),當(dāng)一臺(tái)計(jì)算機(jī)向另外-臺(tái)計(jì)算機(jī)發(fā)送數(shù)據(jù)時(shí),發(fā)送端不會(huì)確認(rèn)接收端是否存在,就會(huì)發(fā)出數(shù)據(jù),同樣接收端在收到數(shù)據(jù)時(shí),也不會(huì)向發(fā)送端反饋是否收到數(shù)據(jù)。
- 由于使用UDP協(xié)議消耗資源小,通信效率高,所以通常都會(huì)用于音頻視頻和普通數(shù)據(jù)的傳輸
- 例如視頻會(huì)議通常采用UDP協(xié)議, 因?yàn)檫@種情況即使偶爾丟失一兩個(gè)數(shù)據(jù)包,也不會(huì)對(duì)接收結(jié)果產(chǎn)生大影響。但是在使用UDP協(xié)議傳送數(shù)據(jù)時(shí),由于UDP的面向無(wú)連接性,不能保證數(shù)據(jù)的完整性,因此在傳輸重要數(shù)據(jù)時(shí)不建議使用UDP協(xié)議
TCP協(xié)議
- 傳輸控制協(xié)議 (Transmission Control Protocol)
- TCP協(xié)議是面向連接的通信協(xié)議,即傳輸數(shù)據(jù)之前,在發(fā)送端和接收端建立邏輯連接,然后再傳輸數(shù)據(jù),它提供了兩臺(tái)計(jì)算機(jī)之間可靠無(wú)差錯(cuò)的數(shù)據(jù)傳輸。在TCP連接中必須要明確客戶端與服務(wù)器端,由客戶端向服務(wù)端發(fā)出連接請(qǐng)求,每次連接的創(chuàng)建都需要經(jīng)過(guò)“三次握手"
- 三次握手:TCP協(xié)議中,在發(fā)送數(shù)據(jù)的準(zhǔn)備階段,客戶端與服務(wù)器之間的三次交互,以保證連接的可靠
- 第一次握手,客戶端向服務(wù)器端發(fā)出連接請(qǐng)求,等待服務(wù)器確認(rèn)
- 第二次握手,服務(wù)器端向客戶端回送一個(gè)響應(yīng), 通知客戶端收到了連接請(qǐng)求
- 第三次握手,客戶端再次向服務(wù)器端發(fā)送確認(rèn)信息,確認(rèn)連接

- 完成三次握手,連接建立后,客戶端和服務(wù)器就可以開(kāi)始進(jìn)行數(shù)據(jù)傳輸了。由于這種面向連接的特性,TCP協(xié)議可以保證傳輸數(shù)據(jù)的安全,所以應(yīng)用十分廣泛。例如上傳文件、下載文件、 瀏覽網(wǎng)頁(yè)等
2 UDP通信程序
2.1 UDP通信原理
UDP協(xié)議是一種不可靠的網(wǎng)絡(luò)協(xié)議,它在通信的兩端各建立一個(gè)Socket對(duì)象, 但是這兩個(gè)Socket只是發(fā)送,接收數(shù)據(jù)的對(duì)象因此對(duì)于基于UDP協(xié)議的通信雙方而言,沒(méi)有所謂的客戶端和服務(wù)器的概念
Java提供了DatagramSocket類作為基于UDP協(xié)議的Socket
2.2 UDP發(fā)送數(shù)據(jù)
- 發(fā)送數(shù)據(jù)的步驟
1、創(chuàng)建發(fā)送端的Socket對(duì)象(DatagramSocket):DatagramSocket()
2、創(chuàng)建數(shù)據(jù), 并把數(shù)據(jù)打包:DatogramPacket (byte[] buf, int Length, InetAddress address, int port)
3、調(diào)用DatagramSocket對(duì)象的方法發(fā)送數(shù)據(jù):void send(DatagramPacket p)
4、關(guān)閉發(fā)送端:void close()
范例
package test;
import java.io.IOException;
import java.net.*;
public class Demo {
public static void main(String[] args) throws IOException {
//1、創(chuàng)建發(fā)送端的Socket對(duì)象(DatagramSocket)
DatagramSocket ds = new DatagramSocket();
//2、創(chuàng)建數(shù)據(jù), 并把數(shù)據(jù)打包
//DatogramPacket (byte[] buf, int Length, InetAddress address, int port)
// 構(gòu)造一個(gè)數(shù)據(jù)包,發(fā)送長(zhǎng)度為length的數(shù)據(jù) 包到指定主機(jī)上的指定端口號(hào)。
byte[] bys = "hello,java".getBytes();
DatagramPacket dp = new DatagramPacket(bys,bys.length, InetAddress.getByName("127.0.0.1"),10086);
//3、調(diào)用DatagramSocket對(duì)象的方法發(fā)送數(shù)據(jù)
//void send(DatagramPacket p)
ds.send(dp);
//4、關(guān)閉發(fā)送端
ds.close();
}
}2.3 UDP接收數(shù)據(jù)
- 接收數(shù)據(jù)的步驟
1、創(chuàng)建接收端的Socket對(duì)象(DatagramSocket):DatagramSocket(int port)
2、創(chuàng)建一個(gè)數(shù)據(jù)包, 用于接收數(shù)據(jù):DatagramPacket(byte[] buf, int length)
3、調(diào)用DatagramSocket對(duì)象的方法接收數(shù)據(jù):void receive(DatagramPacketp)
4、解析數(shù)據(jù)包, 并把數(shù)據(jù)在控制臺(tái)顯示:byte[] getData()、int getLength()
5、關(guān)閉接收端:void close()
package test;
import java.io.IOException;
import java.net.DatagramPacket;
import java.net.DatagramSocket;
public class ReceiveDemo {
public static void main(String[] args) throws IOException {
//1、創(chuàng)建接收端的Socket對(duì)象(DatagramSocket):DatagramSocket(int port)
DatagramSocket ds = new DatagramSocket(10086);
//2、創(chuàng)建一個(gè)數(shù)據(jù)包, 用于接收數(shù)據(jù)
//DatagramPacket(byte[] buf, int length):構(gòu)造一個(gè)DatagramPacket用來(lái)接收長(zhǎng)度為length的數(shù)據(jù)包
byte[] bys = new byte[1024];
DatagramPacket dp = new DatagramPacket(bys, bys.length);
//3、調(diào)用DatagramSocket對(duì)象的方法接收數(shù)據(jù):void receive(DatagramPacketp)
ds.receive(dp);
//4、解析數(shù)據(jù)包, 并把數(shù)據(jù)在控制臺(tái)顯示:
// byte[] getData():返回?cái)?shù)據(jù)緩沖區(qū) int getLength()
byte[] datas = dp.getData();
//int getlength():返回要發(fā)送的數(shù)據(jù)長(zhǎng)度或接收的數(shù)據(jù)長(zhǎng)度
int len = dp.getlength();
String dataString = new String(datas,0,len);
System.out.println("數(shù)據(jù)是:"+dataString);
//5、關(guān)閉接收端:void close()
ds.close();
}
}2.4 范例

發(fā)送端
package test;
import java.io.BufferedReader;
import java.io.IOException;
import java.io.InputStreamReader;
import java.net.DatagramPacket;
import java.net.DatagramSocket;
import java.net.InetAddress;
public class SendDemo {
public static void main(String[] args) throws IOException {
//1、創(chuàng)建發(fā)送端的Socket對(duì)象(DatagramSocket):DatagramSocket()
DatagramSocket ds = new DatagramSocket();
//鍵盤錄入數(shù)據(jù)
BufferedReader br = new BufferedReader(new InputStreamReader(System.in));
String line;
while ((line = br.readLine()) != null) {
if ("886".equals(line)) {
break;
} else {
//創(chuàng)建數(shù)據(jù)并把數(shù)據(jù)打包
byte[] bys = line.getBytes();
DatagramPacket dp = new DatagramPacket(bys, bys.length, InetAddress.getByName("127.0.0.1"), 1001);
//3、調(diào)用DatagramSocket對(duì)象的方法發(fā)送數(shù)據(jù):void send(DatagramPacket p)
ds.send(dp);
}
}
ds.close();
}
}接收端
package test;
import java.io.IOException;
import java.net.DatagramPacket;
import java.net.DatagramSocket;
public class ReceiveDemo {
public static void main(String[] args) throws IOException {
//創(chuàng)建接收端的Socket對(duì)象(DatagramSocket):DatagramSocket(int port)
DatagramSocket ds = new DatagramSocket(1001);
while(true) {
//創(chuàng)建一個(gè)數(shù)據(jù)包接收數(shù)據(jù)
byte[] bys = new byte[1024];
DatagramPacket dp = new DatagramPacket(bys, bys.length);
//調(diào)用DatagramSocket對(duì)象的方法接收數(shù)據(jù):void receive(DatagramPacketp)
ds.receive(dp);
//解析數(shù)據(jù)包, 并把數(shù)據(jù)在控制臺(tái)顯示:byte[] getData()、int getLength()
System.out.println("數(shù)據(jù)是:" + new String(dp.getData(), 0, dp.getLength()));
}
//關(guān)閉
// ds.close();
}
}3 TCP通信程序
3.1 TCP通信原理
TCP通信協(xié)議是一種可靠的網(wǎng)絡(luò)協(xié)議, 它在通信的兩端名建立一個(gè)Socke對(duì)象, 從而在通信的兩端形成網(wǎng)絡(luò)虛擬鏈路一旦建立了 虛擬的網(wǎng)絡(luò)鏈路,兩端的程序就可以通過(guò)虛擬鏈路進(jìn)行通信
Java對(duì)基于TCP協(xié)議的的網(wǎng)絡(luò)提供了良好的封裝,使用Socket對(duì)象來(lái)代表兩端的通信端口,并通過(guò)Socket產(chǎn)生l0流來(lái)進(jìn)行網(wǎng)絡(luò)通信Java為客戶端提供了Socket類,為服務(wù)器端提供了ServerSocket類
3.2 TCP發(fā)送數(shù)據(jù)
- 發(fā)送數(shù)據(jù)的步驟
1、創(chuàng)建客戶端的Socket對(duì)象(Socket):Socket(String host, int port)
2、獲取輸出流,寫(xiě)數(shù)據(jù):OutputStream對(duì)象的getOutputStream()方法
???????3、釋放資源:void close()
范例:
package test;
import java.io.IOException;
import java.io.OutputStream;
import java.net.Socket;
public class ClientDemo {
public static void main(String[] args) throws IOException {
//1、創(chuàng)建客戶端的Socket對(duì)象(Socket):Socket(String host, int port)
Socket s = new Socket("127.0.0.1",1000);
//2、獲取輸出流,寫(xiě)數(shù)據(jù):OutputStream對(duì)象的getOutputStream()方法
OutputStream os = s.getOutputStream();
os.write("hello,java".getBytes());
//3、釋放資源:void close()
s.close();
}
}3.3 TCP接收數(shù)據(jù)
- 接收數(shù)據(jù)的步驟
1、創(chuàng)建服務(wù) 器端的Socket對(duì)象(ServerSocket):ServerSocket(int port)
???????2、監(jiān)聽(tīng)客戶端連接, 返回個(gè)Socket對(duì)象:Socket accept()
???????3、獲取輸入流, 讀數(shù)據(jù),并把數(shù)據(jù)顯示在控制臺(tái):InputStream對(duì)象的getInputStream()方法
???????4、釋放資源:void close()
范例
package test;
import java.io.IOException;
import java.io.InputStream;
import java.net.ServerSocket;
import java.net.Socket;
public class SeverDemo {
public static void main(String[] args) throws IOException {
//1、創(chuàng)建服務(wù) 器端的Socket對(duì)象(ServerSocket):ServerSocket(int port)
ServerSocket ss = new ServerSocket(1000);
//2、監(jiān)聽(tīng)客戶端連接, 返回個(gè)Socket對(duì)象:Socket accept()
Socket s = ss.accept();
//3、獲取輸入流, 讀數(shù)據(jù),并把數(shù)據(jù)顯示在控制臺(tái):InputStream對(duì)象的getInputStream()方法
InputStream is = s.getInputStream();
byte[] bys = new byte[1014];
int len = is.read(bys);
String data = new String(bys,0,len);
System.out.println(data);
//4、釋放資源:void close()
s.close();
ss.close();
}
}3.4 案例
3.4.1 練習(xí)一:服務(wù)器給出反饋

客戶端
package test;
import java.io.IOException;
import java.io.InputStream;
import java.io.OutputStream;
import java.net.Socket;
public class ClientDemo {
public static void main(String[] args) throws IOException {
//1、創(chuàng)建客戶端的Socket對(duì)象(Socket):Socket(String host, int port)
Socket s = new Socket("127.0.0.1",1000);
//2、獲取輸出流,寫(xiě)數(shù)據(jù):OutputStream對(duì)象的getOutputStream()方法
OutputStream os = s.getOutputStream();
os.write("hello,java".getBytes());
//接收服務(wù)器反饋
InputStream is = s.getInputStream();
byte[] bys = new byte[1024];
int len = is.read(bys);
String data = new String(bys,0,len);
System.out.println("客戶端:"+data);
//3、釋放資源:void close()
s.close();
//客戶端:數(shù)據(jù)已經(jīng)收到
}
}服務(wù)器
package test;
import java.io.IOException;
import java.io.InputStream;
import java.io.OutputStream;
import java.net.ServerSocket;
import java.net.Socket;
public class SeverDemo {
public static void main(String[] args) throws IOException {
//1、創(chuàng)建服務(wù) 器端的Socket對(duì)象(ServerSocket):ServerSocket(int port)
ServerSocket ss = new ServerSocket(1000);
//2、監(jiān)聽(tīng)客戶端連接, 返回個(gè)Socket對(duì)象:Socket accept()
Socket s = ss.accept();
//3、獲取輸入流, 讀數(shù)據(jù),并把數(shù)據(jù)顯示在控制臺(tái):InputStream對(duì)象的getInputStream()方法
InputStream is = s.getInputStream();
byte[] bys = new byte[1014];
int len = is.read(bys);
String data = new String(bys,0,len);
System.out.println("服務(wù)器:"+data);
//給出反饋
OutputStream os = s.getOutputStream();
os.write("數(shù)據(jù)已經(jīng)收到".getBytes());
//4、釋放資源:void close()
s.close();
ss.close();
//服務(wù)器:hello,java
}
}3.4.2 練習(xí)二:客戶端數(shù)據(jù)來(lái)源于鍵盤錄入

客戶端
package test;
import java.io.*;
import java.net.Socket;
public class ClientDemo {
public static void main(String[] args) throws IOException {
//創(chuàng)建客戶端的Socket對(duì)象(Socket):Socket(String host, int port)
Socket s = new Socket("127.0.0.1",1000);
//數(shù)據(jù)來(lái)源于鍵盤錄入,直到886停止
System.out.println("請(qǐng)輸入數(shù)據(jù)");
BufferedReader br = new BufferedReader(new InputStreamReader(System.in));
//封裝輸出流對(duì)象
BufferedWriter bw = new BufferedWriter(new OutputStreamWriter(s.getOutputStream()));
String line;
while((line= br.readLine())!=null) {
if("886".equals(line)) {
break;
}
//獲取輸出流對(duì)象
bw.write(line);
bw.newLine();
bw.flush();
}
//釋放資源
s.close();
// hello
// 886
}
}服務(wù)器
package test;
import java.io.*;
import java.net.ServerSocket;
import java.net.Socket;
public class SeverDemo {
public static void main(String[] args) throws IOException {
//1、創(chuàng)建服務(wù) 器端的Socket對(duì)象(ServerSocket):ServerSocket(int port)
ServerSocket ss = new ServerSocket(1000);
//2、監(jiān)聽(tīng)客戶端連接, 返回個(gè)Socket對(duì)象:Socket accept()
Socket s = ss.accept();
//3、獲取輸入流, 讀數(shù)據(jù),并把數(shù)據(jù)顯示在控制臺(tái):InputStream對(duì)象的getInputStream()方法
// InputStream is = s.getInputStream();
// InputStreamReader isr = new InputStreamReader(is);
// BufferedReader br = new BufferedReader(isr);
BufferedReader br = new BufferedReader(new InputStreamReader(s.getInputStream()));
String line;
while((line=br.readLine())!=null) {
System.out.println(line);
}
//4、釋放資源:void close()
s.close();
//hello
}
}3.4.3 練習(xí)三:服務(wù)器數(shù)據(jù)寫(xiě)入文本文件

服務(wù)器
package test;
import java.io.*;
import java.net.ServerSocket;
import java.net.Socket;
public class SeverDemo {
public static void main(String[] args) throws IOException {
//1、創(chuàng)建服務(wù) 器端的Socket對(duì)象(ServerSocket):ServerSocket(int port)
ServerSocket ss = new ServerSocket(1000);
//2、監(jiān)聽(tīng)客戶端連接, 返回個(gè)Socket對(duì)象:Socket accept()
Socket s = ss.accept();
//3、獲取輸入流, 讀數(shù)據(jù),并把數(shù)據(jù)顯示在控制臺(tái):InputStream對(duì)象的getInputStream()方法
BufferedReader br = new BufferedReader(new InputStreamReader(s.getInputStream()));
//把數(shù)據(jù)寫(xiě)入文本文件
BufferedWriter bw = new BufferedWriter(new FileWriter("E:\\test\\java.txt"));
String line;
while((line=br.readLine())!=null) {
bw.write(line);
bw.newLine();
bw.flush();
}
//4、釋放資源:void close()
bw.close();
ss.close();
//文件中數(shù)據(jù):hello
}
}3.4.4 練習(xí)四:客戶端數(shù)據(jù)來(lái)源于文本文件

客戶端
package test;
import java.io.*;
import java.net.Socket;
public class ClientDemo {
public static void main(String[] args) throws IOException {
//創(chuàng)建客戶端的Socket對(duì)象(Socket):Socket(String host, int port)
Socket s = new Socket("127.0.0.1",1000);
//封裝文本文件數(shù)據(jù)
BufferedReader br =new BufferedReader(new FileReader("E:\\test\\fos.txt"));
//封裝輸出流對(duì)象
BufferedWriter bw = new BufferedWriter(new OutputStreamWriter(s.getOutputStream()));
String line;
while((line= br.readLine())!=null) {
//獲取輸出流對(duì)象
bw.write(line);
bw.newLine();
bw.flush();
}
//釋放資源
br.close();
s.close();
}
}3.4.5 練習(xí)五:上傳文件服務(wù)器給出反饋

客戶端
package test;
import java.io.*;
import java.net.Socket;
public class ClientDemo {
public static void main(String[] args) throws IOException {
//創(chuàng)建客戶端的Socket對(duì)象(Socket):Socket(String host, int port)
Socket s = new Socket("127.0.0.1",1000);
//封裝文本文件數(shù)據(jù)
BufferedReader br =new BufferedReader(new FileReader("E:\\test\\fos.txt"));
//封裝輸出流對(duì)象
BufferedWriter bw = new BufferedWriter(new OutputStreamWriter(s.getOutputStream()));
String line;
while((line= br.readLine())!=null) {
//獲取輸出流對(duì)象
bw.write(line);
bw.newLine();
bw.flush();
}
// //自定義結(jié)束標(biāo)記
// bw.write("886");
// bw.newLine();
// bw.flush();
s.shutdownOutput();//Socket類中方法:表示輸出結(jié)束
//接收反饋
BufferedReader brClient = new BufferedReader(new InputStreamReader(s.getInputStream()));
String data = brClient.readLine(); //等待讀取數(shù)據(jù)
System.out.println("服務(wù)器的反饋:"+data); //服務(wù)器的反饋:文件上傳成功
//釋放資源
br.close();
s.close();
}
}服務(wù)端
package test;
import java.io.*;
import java.net.ServerSocket;
import java.net.Socket;
public class SeverDemo {
public static void main(String[] args) throws IOException {
//1、創(chuàng)建服務(wù) 器端的Socket對(duì)象(ServerSocket):ServerSocket(int port)
ServerSocket ss = new ServerSocket(1000);
//2、監(jiān)聽(tīng)客戶端連接, 返回個(gè)Socket對(duì)象:Socket accept()
Socket s = ss.accept();
//3、獲取輸入流, 讀數(shù)據(jù),并把數(shù)據(jù)顯示在控制臺(tái):InputStream對(duì)象的getInputStream()方法
BufferedReader br = new BufferedReader(new InputStreamReader(s.getInputStream()));
//把數(shù)據(jù)寫(xiě)入文本文件
BufferedWriter bw = new BufferedWriter(new FileWriter("E:\\test\\java.txt"));
String line;
while((line=br.readLine())!=null) { //等待讀取數(shù)據(jù)
// if("886".equals(line)) {
// break;
// }
bw.write(line);
bw.newLine();
bw.flush();
}
//給出反饋
BufferedWriter bwServer = new BufferedWriter(new OutputStreamWriter(s.getOutputStream()));
bwServer.write("文件上傳成功");
bwServer.newLine();
bwServer.flush();
//4、釋放資源:void close()
bw.close();
ss.close();
}
}3.4.6 練習(xí)六:多線程實(shí)現(xiàn)文件上傳

服務(wù)端
package test;
import java.io.*;
import java.net.ServerSocket;
import java.net.Socket;
public class SeverDemo {
public static void main(String[] args) throws IOException {
//創(chuàng)建服務(wù) 器端的Socket對(duì)象(ServerSocket):ServerSocket(int port)
ServerSocket ss = new ServerSocket(1000);
while(true) {
//監(jiān)聽(tīng)客戶端連接, 返回個(gè)Socket對(duì)象:Socket accept()
Socket s = ss.accept();
//為每一個(gè)客戶端開(kāi)啟一個(gè)線程
new Thread(new ServerThread(s)).start();
}
}
}服務(wù)端多線程
package test;
import java.io.*;
import java.net.Socket;
public class ServerThread implements Runnable {
private Socket s;
public ServerThread(Socket s) {
this.s = s;
}
@Override
public void run() {
try {
//接收數(shù)據(jù)寫(xiě)入文本文件
BufferedReader br = new BufferedReader(new InputStreamReader(s.getInputStream()));
// BufferedWriter bw = new BufferedWriter(new FileWriter("E:\\test\\java.txt"));
//解決名稱沖突問(wèn)題,上傳到不同文件中
int count = 0;
File file = new File("E:\\test\\["+count+"]java.txt");
while(file.exists()) {
count++;
file = new File("E:\\test\\["+count+"]java.txt");
}
BufferedWriter bw = new BufferedWriter(new FileWriter(file));
String line;
while ((line=br.readLine()) != null) {
bw.write(line);
bw.newLine();
bw.flush();
}
//給出反饋
BufferedWriter bwSever =new BufferedWriter(new OutputStreamWriter(s.getOutputStream()));
bwSever.write("文件上傳成功");
bwSever.newLine();
bwSever.flush();
//釋放資源
s.close();
}catch (IOException e) {
e.printStackTrace();
}
}
}到此這篇關(guān)于Java網(wǎng)絡(luò)編程三要素及通信程序詳解的文章就介紹到這了,更多相關(guān)Java網(wǎng)絡(luò)編程內(nèi)容請(qǐng)搜索腳本之家以前的文章或繼續(xù)瀏覽下面的相關(guān)文章希望大家以后多多支持腳本之家!
相關(guān)文章
Jenkins初級(jí)應(yīng)用之Invoke?Phing?targets插件配置
這篇文章主要為大家介紹了Jenkins初級(jí)應(yīng)用之Invoke?Phing?targets的插件配置,有需要的朋友可以借鑒參考下,希望能夠有所幫助,祝大家多多進(jìn)步早日升職加薪<BR>2022-04-04
淺析Java中ConcurrentHashMap的存儲(chǔ)流程
ConcurrentHashMap技術(shù)在互聯(lián)網(wǎng)技術(shù)使用如此廣泛,幾乎所有的后端技術(shù)面試官都要在ConcurrentHashMap技術(shù)的使用和原理方面對(duì)小伙伴們進(jìn)行360°的刁難,本文詳細(xì)給大家介紹一下ConcurrentHashMap的存儲(chǔ)流程,需要的朋友可以參考下2023-05-05
Java導(dǎo)出多個(gè)excel表打包到zip文件中供客戶端另存為窗口下載實(shí)現(xiàn)方法
最近的項(xiàng)目有一個(gè)導(dǎo)出匯總數(shù)據(jù)的要求,考慮到用戶軟件的差異,所以要分別導(dǎo)出xls以及xlsx并且打包提供下載,下面這篇文章主要給大家介紹了關(guān)于Java導(dǎo)出多個(gè)excel表打包到zip文件中供客戶端另存為窗口下載的實(shí)現(xiàn)方法,需要的朋友可以參考下2023-12-12
利用Spring Cloud Config結(jié)合Bus實(shí)現(xiàn)分布式配置中心的步驟
這篇文章主要介紹了利用Spring Cloud Config結(jié)合Bus實(shí)現(xiàn)分布式配置中心的相關(guān)資料,文中通過(guò)示例代碼將實(shí)現(xiàn)的步驟一步步介紹的非常詳細(xì),對(duì)大家的學(xué)習(xí)或者工作具有一定的參考學(xué)習(xí)價(jià)值,需要的朋友下面來(lái)一起看看吧2018-05-05
java原裝代碼完成pdf在線預(yù)覽和pdf打印及下載
本文主要介紹了java原裝代碼完成pdf在線預(yù)覽和pdf打印及下載的方法,具有一定的參考價(jià)值,下面跟著小編一起來(lái)看下吧2017-02-02
Mybatis?saveAndUpdate空值不更新問(wèn)題及解決
這篇文章主要介紹了Mybatis?saveAndUpdate空值不更新問(wèn)題及解決方案,具有很好的參考價(jià)值,希望對(duì)大家有所幫助。如有錯(cuò)誤或未考慮完全的地方,望不吝賜教2023-02-02
SpringBoot手把手實(shí)現(xiàn)生成PDF功能的示例代碼
這篇文章主要介紹了如何使用Thymeleaf模板和iText庫(kù)配合Flying-pdf工具,實(shí)現(xiàn)在業(yè)務(wù)系統(tǒng)中生成PDF文件的功能,感興趣的小伙伴可以了解下2025-12-12

