目的:網(wǎng)絡(luò)編程:在兩臺(tái)不同的計(jì)算機(jī)之間數(shù)據(jù)傳遞
服務(wù)器端與客戶端的數(shù)據(jù)傳輸蔚舀,單向傳遞蟆盹,雙向傳遞刃泡,終端接收數(shù)據(jù)傳遞等巧娱。
-
上傳與下載:
客戶端 1.文本 2.圖片 3.音頻 4.視頻 服務(wù)器端、
技術(shù):
知識(shí)點(diǎn):
* 網(wǎng)絡(luò)編程:在兩臺(tái)不同的計(jì)算機(jī)之間數(shù)據(jù)傳遞
* 1.QQ聊天
* 2.打開(kāi)網(wǎng)易APP 刷新界面 就有數(shù)據(jù)
* 3.打開(kāi)瀏覽器 網(wǎng)頁(yè)www.baidu.com
*
* 客戶端:手機(jī)APP 瀏覽器 桌面QQ
* 服務(wù)器端:存儲(chǔ)/處理數(shù)據(jù)
*
* URL : 統(tǒng)一的資源定位
* http://www.baidu.com/search?code=android&type=1
* http/https: 傳輸協(xié)議 Tcp/IP 具體實(shí)現(xiàn)
* www.baidu.com :域名 表示一臺(tái)網(wǎng)絡(luò)中的電腦
* (ipv4烘贴、ipv6)ip地址 : 唯一標(biāo)識(shí)一臺(tái)網(wǎng)絡(luò)中的電腦
* 32位:四個(gè)部分每個(gè)8個(gè)字節(jié)
* 192.168.43.117 <-> www.baidu.com
*
* DNS服務(wù)器: 域名解析
* 將www.baidu.com類型的域名解析為對(duì)應(yīng)的Ip地址
*
* search 對(duì)應(yīng)的后臺(tái)程序文件 php java jsp
* ? 表示運(yùn)行這個(gè)程序需要傳遞的參數(shù)
* code=android :code是服務(wù)器段指定的字段
* & 如果有多個(gè)參數(shù) 使用&符號(hào)鏈接
*
* ip地址唯一標(biāo)識(shí)某一臺(tái)電腦
* 端口號(hào):唯一標(biāo)識(shí)電腦上的某一個(gè)進(jìn)程(程序)80
*
* 數(shù)據(jù)傳輸:TCP/IP協(xié)議
* TCP : 面向鏈接的 安全 如打電話
* UTP : 面向不鏈接的 不安全 快 如古代飛鴿傳書(shū)
*
* 網(wǎng)絡(luò)中的數(shù)據(jù)傳輸:Socket實(shí)現(xiàn) -> 套接字
* Socket類: 客戶端
* ServerSocket服務(wù)器端
*
* 讀取數(shù)據(jù): 服務(wù)器端讀取 客戶端讀取
* BufferReader -> InputStreamReader -> socket.getInputStream()
* 從終端讀冉怼:
* BufferReader -> InputStreamReader -> System.in
* 輸出數(shù)據(jù):客戶端輸出 服務(wù)器端輸出
* BufferedWriter -> OutputStreamWriter -> socket.getOutputStream
* PrintStream -> socket.getOutputStream
實(shí)際編程:
(1).簡(jiǎn)單的服務(wù)器端與客戶端數(shù)據(jù)傳輸;
定義客戶端:
//模擬客戶端
class Client{
public static void main(String[] args) throws IOException {
//1.創(chuàng)建用于通信的Socket
//指明和誰(shuí)通信:IP地址 端口號(hào)
Socket socket = new Socket("192.168.43.117",8989);
//接收服務(wù)器端的數(shù)據(jù)
BufferedReader br = new BufferedReader(new InputStreamReader(socket.getInputStream()));
String line = null;
while ((line = br.readLine()) != null){
System.out.println(line);
}
//向服務(wù)器端發(fā)送數(shù)據(jù)
//socket.getOutputStream();
PrintStream ps = new PrintStream(socket.getOutputStream());
ps.println("你好啊");
//輸出完畢
socket.shutdownOutput();
}
}
定義服務(wù)器端:
//模擬服務(wù)器端
class Server{
public static void main(String[] args) throws IOException {
//1.創(chuàng)建服務(wù)器端的serverSocket
ServerSocket ss = new ServerSocket(8989);
//2.獲取鏈接的客戶端的socket
Socket clientSocket = ss.accept();
//3.向客戶端發(fā)送數(shù)據(jù)
//BufferedWriter bw = new BufferedWriter(new OutputStreamWriter(clientSocket.getOutputStream()));
PrintStream ps = new PrintStream(clientSocket.getOutputStream());
ps.println("登錄成功");
//輸出完畢
clientSocket.shutdownOutput();
//4.接收客戶端發(fā)來(lái)的數(shù)據(jù)
BufferedReader br = new BufferedReader(new InputStreamReader(clientSocket.getInputStream()));
String line = null;
while ((line = br.readLine()) != null){
System.out.println(line);
}
}
}
調(diào)用時(shí)必須先運(yùn)行服務(wù)器端再運(yùn)行客戶端。
(2)手動(dòng)輸入內(nèi)容 發(fā)送
以上代碼進(jìn)行簡(jiǎn)單更改:
class MyClient{
public static void main(String[] args){
//連接服務(wù)器端的Socket
Socket socket = null;
try {
socket = new Socket("192.168.43.117", 8888);
//接收服務(wù)器信息
BufferedReader br = new BufferedReader(new InputStreamReader(socket.getInputStream()));
String line = null;
while ((line = br.readLine()) != null){
System.out.println(line);
}
// //從終端輸出數(shù)據(jù)桨踪,發(fā)送給服務(wù)器端
// //獲取終端數(shù)據(jù)
// BufferedReader keyin = new BufferedReader(new InputStreamReader(System.in));
// //獲取向客戶端的輸出數(shù)據(jù)的輸出流
// PrintStream ps = new PrintStream(socket.getOutputStream());
// String txet = null;
// while ((txet = keyin.readLine()) != null){
// ps.println(txet);
// }
}catch (IOException e){
System.out.println("網(wǎng)絡(luò)出錯(cuò) 請(qǐng)重新登錄");
}finally {
try{
socket.close();
} catch (IOException e) {
e.printStackTrace();
}
}
}
}
class MyServer{
public static void main(String[] args){
//創(chuàng)建ServerSocket
try(ServerSocket serverSocket = new ServerSocket(8888)){
//監(jiān)聽(tīng)客服端的連接
Socket clientSocket = serverSocket.accept();
//從終端接收數(shù)據(jù)
BufferedReader keyin = new BufferedReader(new InputStreamReader(System.in));
//獲取向客戶端的輸出數(shù)據(jù)的輸出流
PrintStream ps = new PrintStream(clientSocket.getOutputStream());
String line = null;
while ((line = keyin.readLine()) != null){
//發(fā)送給客戶端
ps.println(line);
}
// //接收客戶端的數(shù)據(jù)
// BufferedReader br = new BufferedReader(new InputStreamReader(clientSocket.getInputStream()));
// String text = null;
// while ((text = br.readLine()) != null){
// System.out.println(text);
// }
}catch (IOException e){
e.printStackTrace();
}
}
}
(3) * 客戶端向服務(wù)器端發(fā)送圖片 post上傳
class Client1{
public static void main(String[] args) throws IOException {
//連接服務(wù)器 獲取socket
Socket socket = new Socket("192.168.43.117", 9999);
//創(chuàng)建服務(wù)器端對(duì)應(yīng)的輸入流 用于接收服務(wù)器端發(fā)來(lái)的數(shù)據(jù)
BufferedReader br = new BufferedReader(new InputStreamReader(socket.getInputStream()));
System.out.println(br.readLine());
//向服務(wù)器端發(fā)送文件(圖片)
//1.將文件寫(xiě)入內(nèi)存里面
String path = "C:\\Users\\DELL\\Desktop\\1.png";
FileInputStream fis = new FileInputStream(path);
// //2老翘,將內(nèi)容輸出到服務(wù)器端
// PrintStream ps= new PrintStream(socket.getOutputStream());
//
// //3.將文件的內(nèi)容一點(diǎn)一點(diǎn)地傳送給服務(wù)器
// byte[] buf = new byte[1024];
// int len = -1;
// while ((len = fis.read(buf)) != -1){
// ps.println(new String(buf,0,len));
// }
//2.創(chuàng)建字節(jié)流 outputStream
BufferedOutputStream bos = new BufferedOutputStream(socket.getOutputStream());
byte[] buf = new byte[1024];
int len = -1;
while ((len = fis.read(buf)) != -1){
bos.write(buf,0,len);
}
socket.shutdownOutput();
}
}
class Server1{
public static void main(String[] args) throws IOException {
//創(chuàng)建服務(wù)器端的ServerSocket
ServerSocket ss = new ServerSocket(9999);
//監(jiān)聽(tīng)客戶端鏈接
//當(dāng)有客戶端來(lái)連接這個(gè)服務(wù)器 就可以得到對(duì)應(yīng)的socket
//當(dāng)沒(méi)有客戶端連接 服務(wù)器一直在這里等待
Socket socket = ss.accept();
//創(chuàng)建客戶端對(duì)應(yīng)的輸出流 用于向這個(gè)客戶端發(fā)送數(shù)據(jù)
PrintStream ps = new PrintStream(socket.getOutputStream());
ps.println("連接成功 可以發(fā)送數(shù)據(jù)!");
// //接收客戶端傳遞過(guò)來(lái)的圖片
// BufferedReader br = new BufferedReader(new InputStreamReader(socket.getInputStream()));
//
// //文件對(duì)應(yīng)的輸出流
// String path = "E:\\JavaStudy\\JavaXuexi\\src\\main\\java\\day12\\2.png";
// PrintStream psFile = new PrintStream(new FileOutputStream(path));
//
// String line = null;
// char[] buf = new char[1024];
// int len = -1;
// while ((len = br.read(buf)) != -1){
// //將字符數(shù)組轉(zhuǎn)化為字符串
// line = new String(buf,0,len);
// //將字符串寫(xiě)入到文件
// psFile.println(line);
BufferedInputStream bis = new BufferedInputStream(socket.getInputStream());
String path = "E:\\JavaStudy\\JavaXuexi\\src\\main\\java\\day12\\2.png";
FileOutputStream fos = new FileOutputStream(path);
byte[] buf = new byte[1024];
int len = -1;
while((len = bis.read(buf)) != -1){
fos.write(buf,0,len);
}
}
}
(4) 服務(wù)器端與客戶端 對(duì)聊
- 客戶端好服務(wù)器端都可以隨意地發(fā)送內(nèi)容
- 從終端輸入
- 客戶端:
主線程:接收終端輸入 將終端輸入發(fā)送給服務(wù)器端
子線程:接收服務(wù)器端發(fā)過(guò)來(lái)的數(shù)據(jù)
服務(wù)器端:
主線程:接收終端輸入 將1終端輸入發(fā)送給客戶端
子線程:接收客戶端發(fā)過(guò)來(lái)的數(shù)據(jù)
定義Clinet,Server類主線程:
class Client {
public static void main(String[] args) throws IOException {
Socket socket = new Socket("192.168.43.117", 8888);
//子線程 處理服務(wù)端數(shù)據(jù)
new Thread(new ClientThread(socket)).start();
BufferedReader keyin = new BufferedReader(new InputStreamReader(System.in));
//客戶端的輸出流對(duì)象
PrintStream printStream = new PrintStream(socket.getOutputStream());
String line = null;
while ((line = keyin.readLine()) != null) {
printStream.println(line);
}
}
}
class Server{
public static void main(String[] args) throws IOException {
ServerSocket ss = new ServerSocket(8888);
//獲取客戶端的socket
Socket socket = ss.accept();
//創(chuàng)建子線程 處理客戶端的輸入信息
new ServerThread(socket).start();
//終端輸入流對(duì)象
BufferedReader keyin = new BufferedReader(new InputStreamReader(socket.getInputStream()));
//客戶端的輸出流對(duì)象
PrintStream ps = new PrintStream(socket.getOutputStream());
String line = null;
while ((line = keyin.readLine()) != null){
ps.println(line);
}
}
}
實(shí)現(xiàn)子線程锻离,用于接收服務(wù)器端或客戶端的數(shù)據(jù):
/**
* 創(chuàng)建子線程處理客戶端接收服務(wù)器端的數(shù)據(jù)
*/
class ClientThread implements Runnable{
private Socket socket;
//保存操作的socket 對(duì)象
public ClientThread(Socket socket){
this.socket = socket;
}
@Override
public void run() {
BufferedReader bufferedReader = null;
try {
//獲取輸入
bufferedReader = new BufferedReader(new InputStreamReader(socket.getInputStream()));
//讀取
String line = null;
while ((line = bufferedReader.readLine()) != null){
System.out.println(line);
}
} catch (IOException e) {
System.out.println("網(wǎng)絡(luò)出錯(cuò) 請(qǐng)重新登錄");
System.exit(-1);
}finally {
try {
if (bufferedReader != null) {
bufferedReader.close();
}
if (socket != null) {
socket.close();
}
}catch (IOException e) {
e.printStackTrace();
}
}
}
}
/**
* 創(chuàng)建一個(gè)子線程處理服務(wù)器端接收客戶端的數(shù)據(jù)
*/
class ServerThread extends Thread{
private Socket socket;
public ServerThread(Socket socket){
this.socket = socket;
}
@Override
public void run() {
BufferedReader br = null;
try {
br = new BufferedReader(new InputStreamReader(socket.getInputStream()));
//讀取數(shù)據(jù)
String line = null;
while ((line = br.readLine()) != null){
System.out.println(line);
}
} catch (IOException e) {
System.out.println("網(wǎng)絡(luò)異常 請(qǐng)重新登錄");
System.exit(-1);
}finally {
//
//
try{
if(br != null){
br.close();
}
if(socket != null){
socket.close();
}
}catch (IOException e) {
e.printStackTrace();
}
}
}
}
5..如何實(shí)現(xiàn)群聊
重點(diǎn)思想:在服務(wù)器端維護(hù)一個(gè)數(shù)組(socket)
實(shí)現(xiàn)服務(wù)器端:
class Server{
//保存每一個(gè)來(lái)連接的socket對(duì)象
public static ArrayList<Socket> sockets = new ArrayList<>();
public static void main(String[] args) throws IOException {
ServerSocket serverSocket = new ServerSocket(9999);
//不停地等待客戶端來(lái)連接
while (true){
Socket socket = serverSocket.accept();
//保存每一個(gè)客戶端socket
sockets.add(socket);
//開(kāi)啟一個(gè)線程處理每一個(gè)客戶端的輸出
new ServerThread(socket).start();
}
}
}
實(shí)現(xiàn)Server接收每個(gè)客戶端數(shù)據(jù)傳輸:
/**
* 創(chuàng)建一個(gè)子線程處理服務(wù)器端接收客戶端的數(shù)據(jù)
*/
class ServerThread extends Thread{
private Socket socket;
public ServerThread(Socket socket){
this.socket = socket;
}
@Override
public void run() {
BufferedReader br = null;
try {
br = new BufferedReader(new InputStreamReader(socket.getInputStream()));
//讀取數(shù)據(jù)
String line = null;
while ((line = br.readLine()) != null){
//群發(fā)消息
//遍歷Socket維護(hù)的數(shù)組
for(Socket s : Server.sockets){
//向socket對(duì)應(yīng)的客戶端發(fā)送消息
PrintStream ps = new PrintStream(s.getOutputStream());
ps.println(line);
}
}
} catch (IOException e) {
System.out.println("網(wǎng)絡(luò)異常 請(qǐng)重新登錄");
System.exit(-1);
}finally {
//
//
try{
if(br != null){
br.close();
}
if(socket != null){
socket.close();
}
}catch (IOException e) {
e.printStackTrace();
}
}
}
}
客戶端實(shí)現(xiàn)與對(duì)聊的代碼一樣:
class Client{
public static void main(String[] args) throws IOException {
Socket socket = new Socket("10.129.28.253",6666);
//用一個(gè)子線程處理服務(wù)器端數(shù)據(jù)
new Thread(new ClientThread(socket)).start();
//主線程處理終端輸入 發(fā)送給服務(wù)器端
BufferedReader keyin = new BufferedReader(new InputStreamReader(socket.getInputStream()));
PrintStream ps = new PrintStream(socket.getOutputStream());
String line = null;
while ((line = keyin.readLine()) != null){
ps.println(line);
}
}
}
/**
* 創(chuàng)建子線程處理客戶端接收服務(wù)器端的數(shù)據(jù)
*/
class ClientThread implements Runnable{
private Socket socket;
public ClientThread(Socket socket){
this.socket = socket;
}
@Override
public void run() {
BufferedReader br = null;
try {
//獲取服務(wù)器端的輸入流對(duì)象
br = new BufferedReader(new InputStreamReader(socket.getInputStream()));
//讀取數(shù)據(jù)
String line = null;
while ((line = br.readLine()) != null){
System.out.println(line);
}
}catch (IOException e){
e.printStackTrace();
}finally {
try{
if(br != null){
br.close();
}
if(socket != null){
socket.close();
}
}catch (IOException e) {
e.printStackTrace();
}
}
}
}
心得:
今天循環(huán)寫(xiě)差不多的代碼铺峭。頭都搞暈了,晚自習(xí)時(shí)是在沒(méi)精神啊纳账,但效果真的不錯(cuò)逛薇,復(fù)習(xí)時(shí)輕輕松松,因?yàn)槎加杏∠蟆?/p>