01 網(wǎng)絡(luò)編程的三要素
1.協(xié)議:能夠保證數(shù)據(jù)傳輸通暢
2.IP地址:定義到網(wǎng)絡(luò)中的某個(gè)終端設(shè)備
3.端口:定位到這個(gè)終端設(shè)備部的具體的進(jìn)程
客戶端程序Socket
類的使用:
1)創(chuàng)建對(duì)象
public Socket(String host,int port):可以連接指定地址,指定端口的服務(wù)器
2)使用方法:
public OutputStream getIutputStream():獲取輸入流:從網(wǎng)絡(luò)中讀取數(shù)據(jù)
public OutputStream getOutputStream():獲取輸出流,寫出數(shù)據(jù)到網(wǎng)絡(luò)
public void shoudownOutput():關(guān)閉輸出流,發(fā)送接收標(biāo)記,不會(huì)關(guān)閉連接。
public void close():關(guān)閉Socket連接
步驟:
1)要?jiǎng)?chuàng)建Socket對(duì)象,連接指定的服務(wù)端
2)獲得輸出流,寫出數(shù)據(jù)
3)關(guān)閉輸出流
4)獲取輸入流,讀取數(shù)據(jù)
5)關(guān)閉連接
02TCP 服務(wù)端編程
SeverSocket;服務(wù)端的類
創(chuàng)建對(duì)象
public ServerSocket(int port):監(jiān)聽本地的端口號(hào)
常用方法
public Socket accept():接收服務(wù)端的連接,如果客戶端沒(méi)有連接過(guò)來(lái),該方法處于阻塞狀態(tài)【一直等客戶端連接過(guò)來(lái)】
public void close
步驟:
1)創(chuàng)建服務(wù)器端ServerSocket對(duì)象,監(jiān)聽指定端口;
2)接收客戶端的連接,獲取對(duì)應(yīng)的Socket對(duì)象【accept】
3)獲取對(duì)象的輸入流,獲得客戶端寫出的數(shù)據(jù)
4)獲取客戶端的輸出流,寫出數(shù)據(jù)到客戶端
5)告訴客戶端寫出數(shù)據(jù)完畢【shutdownOutput】
6)關(guān)閉socket對(duì)象連接
7)關(guān)閉服務(wù)器
03文件上傳客戶端實(shí)現(xiàn)
/*
客戶端: 讀取本地得文件寫出到網(wǎng)絡(luò)
?
步驟分析:
1)創(chuàng)建Socket對(duì)象和服務(wù)端建立連接
2)先獲取本地得文件數(shù)據(jù)【輸入流】,獲取網(wǎng)絡(luò)數(shù)據(jù)流 【邊讀邊寫】
3)告訴服務(wù)端,我數(shù)據(jù)發(fā)送完畢
4)接收服務(wù)端數(shù)據(jù)
5)關(guān)閉socket連接
文件上傳服務(wù)端:ServerSocket
就是讀取網(wǎng)絡(luò)中的數(shù)據(jù),寫出到本地中去
*/
public class Client{
public static void main(String[]args)throws IO Exception{
//1)創(chuàng)建Socket對(duì)象和服務(wù)端建立連接
Socketsocket=newSocket("127.0.0.1",8888);
//2)先獲取本地得文件數(shù)據(jù)【輸入流】,獲取網(wǎng)絡(luò)數(shù)據(jù)流 【邊讀邊寫】
FileInputStreamlocalIn=newFileInputStream("client/beauty.jpg");
OutputStreamnetOut=socket.getOutputStream();
?
int len;
byte[]bytes=newbyte[1024];
while((len=localIn.read(bytes))!=-1) {//讀取本地?cái)?shù)據(jù)
netOut.write(bytes,0,len);// 寫出數(shù)據(jù)到網(wǎng)絡(luò)
? ? ?? }
?
//3)告訴服務(wù)端,我數(shù)據(jù)發(fā)送完畢
socket.shutdownOutput();
//4)接收服務(wù)端數(shù)據(jù)
InputStreamnetIn=socket.getInputStream();
while((len=netIn.read(bytes))!=-1) {
System.out.println(newString(bytes,0,len));
? ? ?? }
?
//5)關(guān)閉socket連接
socket.close();
?
?? }
}
04文件上傳服務(wù)端實(shí)現(xiàn)
1)創(chuàng)建服務(wù)器對(duì)象:ServerSocket
2)等待客戶端連接,得到socket對(duì)象:accept
3)讀取網(wǎng)絡(luò)中的數(shù)據(jù)并寫出到本地硬盤
3.1通過(guò)socket對(duì)象獲取網(wǎng)絡(luò)輸入流
3.2創(chuàng)建本地的輸出流用來(lái)寫出數(shù)據(jù)
4)發(fā)送一個(gè)信息給客戶端,完成上傳
5)關(guān)閉socket連接
6)關(guān)服務(wù)器
publicclassServer{
publicstaticvoidmain(String[]args)throwsIOException{
//1)創(chuàng)建服務(wù)端對(duì)象:ServerSocket
ServerSocketserverSocket=newServerSocket(8888);
//2)等待客戶端連接,得到socket對(duì)象:accept
System.out.println("等待客端連接....");
Socketsocket=serverSocket.accept();
System.out.println("客端連接成功...."+socket.getInetAddress());
//3)讀取網(wǎng)絡(luò)中得數(shù)據(jù)并寫出到本地磁盤
//3.1 通過(guò)socket對(duì)象獲取網(wǎng)絡(luò)輸入流
//3.2 創(chuàng)建本地得輸出流用來(lái)寫出數(shù)據(jù)
InputStreamnetIn=socket.getInputStream();
FileOutputStreamlocalOut=newFileOutputStream("server/beauty.jpg");
intlen;
byte[]bytes=newbyte[1024];
while((len=netIn.read(bytes))!=-1) {//讀取網(wǎng)絡(luò)數(shù)據(jù)
localOut.write(bytes,0,len);// 將數(shù)據(jù)寫到本地磁盤
? ? ?? }
//4)發(fā)一個(gè)信息給客戶端,完成上傳
OutputStreamnetOut=socket.getOutputStream();
netOut.write("恭喜,文件上傳成功".getBytes());
socket.shutdownOutput();
//5)關(guān)socket連接
socket.close();
//6)關(guān)服務(wù)器
serverSocket.close();
?? }
}
05 上傳案例的服務(wù)端優(yōu)化
解決問(wèn)題
1)文件名重復(fù):
解決方案:命名文件的時(shí)候,加上時(shí)間戳
FileOutputStream localOut = new FileOutputStream("server/beauty"+System.currentTimeMillis()+".jpg");
2)只能服務(wù)一次
? ? 使用while(true){
? ? ? ? 接收客端
? ? ? ? 傳輸數(shù)據(jù)
? ? }
? ? 低效
3)效率
? ? 多線程解決
? ? 線程池
? ? 1)創(chuàng)建線程池
? ? 2)創(chuàng)建任務(wù):傳輸數(shù)據(jù)
? ? 3)提交任務(wù)