1? ? ? 網絡編程----TCPNo24
【
public class Server {
public static void main(String[] args){
try {
ServerSocket ss =new ServerSocket(8888);//在8888端口上建立ServerSocket
Socket s =ss.accept();//監聽客戶端的連接請求,一旦連接請求到達,建立連接,會返回一個服務器端的Socket
InputStream is =s.getInputStream();//獲取這個Socket的輸入流,用于讀取客戶端傳來的信息
int b = is.read();//讀一個字節
System.out.println(b);//打印
s.close();//關閉和客戶端的連接
ss.close();//關閉ServerSocket,之后不再去監聽端的連接請求
} catch (IOException e) {
// TODOAuto-generated catch block
e.printStackTrace();
}
}
}
public class Client {
public static void main(String[] args){
try {
Socket s = newSocket("127.0.0.1",8881);//向本機8888端口發送連接請求
OutputStream os =s.getOutputStream();//獲取客戶端Socket的輸出流
os.write(100);//寫一個字節100
s.close();//關閉套接字
} catch (IOException e) {
// TODOAuto-generated catch block
e.printStackTrace();
}
}
}
】
Protocol協議就是一種格式、約定,網絡兩端的主機可以根據這個約定來進行信息的交互和傳輸
網絡四層協議體系架構TCP/IP
1、應用層? http、ftp
2、傳輸層? TCP、UDP
3、網絡互聯層? IP
4、主機到網絡層
InetAddress類的使用:【
getByName(Stringhost):根據主機名獲取IP對象
getHostAddress():獲取主機地址
getHostName():獲取主機名
getAllByName(Stringhost):獲取主機名獲取所有的IP對象
getLocalHost():獲取本地主機對應的IP地址(127.0.0.1)
示例代碼
//在Java中,使用InetAddress類描敘網絡地址
InetAddress inetAddr = null;
//創建InetAddress對象
//在互聯網上訪問服務器有兩種形式:1、ip地址?? 2、主機名(例如:http://www.baidu.com)
//?????????????? inetAddr =InetAddress.getByName("www.baidu.com");
//?????????????? inetAddr =InetAddress.getByName("192.168.35.1");
//?????????????? inetAddr =InetAddress.getByName("192.168.81.144");
//?????????????? inetAddr = InetAddress.getByName("localhost");
//獲取本機ip地址
inetAddr =InetAddress.getLocalHost();
//ip地址
String address =inetAddr.getHostAddress();
//主機名
String host =inetAddr.getHostName();
System.out.println(address+":"+host);
InetAddress[] inetAddresses=InetAddress.getAllByName("www.baidu.com");
for (InetAddress inet :inetAddresses) {
System.out.println(inet.getHostAddress());
}
】
【
IP地址:網絡中每臺主機都必須有一個唯一的IP地址(網絡中設備的標識)
端口:用于標識進程的邏輯地址,每個進程都有各自不同的標識, 有效端口0~65535,其中0-1024系統使用或保留端口
傳輸協議:UDP---《將數據、源地址和目的地址封裝在數據報包中;每個數據報的大小被限制在64K以內;不需要建立連接;是不可靠協議,速度快》
TCP----《建立連接,形成傳輸數據的通道;在連接中進行大數據傳輸;通過三次握手完成連接;必須建立連接;是可靠協議,效率較低》
【1. 客戶端向服務器發送包含初始序列值的數據段,開啟通信會話
2.????? 服務器發送包含確認值的數據段,其值等于收到的序列值加1,并加上其自身的同步序列值
3.????? 發送帶確認值的客戶端響應,其值等于接受的序列值加1.這便完成了整個建立連接的過程】
】
1、Socket是為了網絡服務而提供的一種機制;
2、套接字是兩臺機器間通信的端點;
3、網絡通信其實就是Socket間的通信(所以網絡編程又稱為Socket編程);
4、Socket之間通過IO流來進行數據的傳輸(TCP);
5、Socket = IP地址 + 端口
】
TCP? Transmit Control Protocol傳輸控制協議
可以將IP報文進行包裝、組織,有序可靠地傳輸到網絡另一端
是基于連接的,兩個主機在進行通信前必須先建立連接(三次握手)
(UDPUser Datagram protocol用戶數據報協議,不需要連接,信息傳輸會發生丟失)
協議都是跨語言、跨平臺的
如何用Java來進行TCP通信:
ServerSocket服務器套接字,用來監聽客戶端發送來的連接請求,一旦有客戶端請求連接,就可以生成一個連接,并獲取服務端這頭的Socket
構造方法:ServerSocket(int port)在端口port上建立服務端套接字
Socketaccept()監聽客戶端過來的連接請求,是一個阻塞方法,連接請求過來了,它就會返回建立的連接的服務端這頭的套接字,這個套接字可以用來向客戶端寫或者從客戶端讀信息
Socket套接字,就是網絡上兩臺主機之間建立的連接的兩個端點,可以通過它寫信息,也可以讀信息(套接字可以用于兩臺連接的主機之間進行通信,讀寫信息。)
一:服務端
getOutputStream()獲取套接字輸出流
write系列方法,使用和文件IO中差不多
getInputStream()獲取套接字輸入流
read系列方法
二:客戶端
構造方法:Socket(String address,int port)參數為服務端的地址以及端口號,這樣構建時就能發送一個連接請求到服務端,接下來這個創建出來的Socket對象就能用來和服務端通信
getOutputStream()獲取套接字輸出流
write系列方法,使用和文件IO中差不多
getInputStream()獲取套接字輸入流
read系列方法
getPort()獲取端口號
getInetAddress()獲取英特網地址對象(可以調用這個對象的getHostAddress()獲取地址字符串)
另有一個4參構造方法Socket(String address,int port,InetAddress addr,int p)可以用第四個參數指定客戶端的端口(2參構造方法的客戶端端口隨機分配)
Socket類:此類實現客戶端套接字
ServerSocket:《此類實現服務器套接字。服務器套接字等待請求通過網絡傳入。它基于該請求執行某些操作,然后可能向請求者返回結果。
PS:在創建Socket對象時,底層會自動創建一個客戶端與服務端之間的通道,這個通道就是Socket流(網絡IO流),Socket流既包含輸入流,又包含輸出流。》
使用步驟:
客戶端:【《
1、 創建套接字對象(需要綁定指定的服務器ip地址和端口)
2、 通過IO流和服務端傳輸數據
3、 關閉Socket,釋放資源》
服務端:【《
1、 創建服務端套接字對象(需要綁定端口,以便客戶端連接)
2、 等待接收來自客戶端的連接請求
3、 通過IO流與客戶端傳輸數據
4、 關閉資源》
】
代碼:
【
Client.java客戶端
publicclassClient {
publicstaticvoidmain(String[]args)throwsUnknownHostException, IOException {
//tcp的客戶端
System.out.println("tcp客戶端開啟...");
/*
*創建Socket對象,當執行這行代碼的時候底層會自動和服務端建立連接(三次握手)
*如果連接建立不成功,就會拋出異常
*/
//Socket socket = newSocket("127.0.0.1", 9999);
Socketsocket=newSocket("192.168.81.143", 9999);
//獲取IO流對象,通過IO流對象可以實現與服務端的數據傳輸
// socket.getInputStream();
OutputStreamos=socket.getOutputStream();
os.write("來自tcp客戶端的數據".getBytes());
//釋放資源,斷開與服務端的連接
socket.close();
System.out.println("tcp客戶端關閉...");
}
}
服務端:Server.java
publicclass Server {
public static void main(String[] args)throws IOException {
// tcp的服務端
System.out.println("tcp服務端開啟...");
// 創建服務端的套接字對象,用于響應來自客戶端的連接請求
ServerSocket serverSocket =new ServerSocket(9999);
// 等待接收來自客戶端的連接請求,連接成功后會返回與客戶端對應的Socket對象
Socket socket =serverSocket.accept(); // 阻塞式方法
// 獲取客戶端的ip地址
String ip =socket.getInetAddress().getHostAddress();
System.out.println("與" + ip + "建立連接");
InputStream is =socket.getInputStream();
// socket.getOutputStream();
byte[] buf = new byte[1024];
int length = is.read(buf);
System.out.println(ip +":" + new String(buf, 0, length));
// socket.close();
// 釋放資源,關閉服務端的套接字,會斷開所有的客戶端連接
serverSocket.close();
System.out.println("tcp服務端關閉");
}
}
】
【
publicclass Client {
public static void main(String[] args)throws UnknownHostException,
IOException {
// tcp的客戶端
System.out.println("tcp客戶端開啟...");
Socket socket = newSocket("192.168.81.143", 9999);
Scanner scanner = newScanner(System.in);
/*BufferedReader br = newBufferedReader(new InputStreamReader(
socket.getInputStream()));*/
BufferedWriter bw = newBufferedWriter(new OutputStreamWriter(
socket.getOutputStream()));
for(;;){
String line =scanner.nextLine();
bw.write(line);
bw.newLine();
bw.flush();
}
//?????????????? socket.close();
//?????????????? System.out.println("tcp客戶端關閉...");
}
}
publicclass Server {
public static void main(String[] args)throws IOException {
// TODO Auto-generated methodstub
// tcp服務端
System.out.println("TCP服務端開啟.....");
ServerSocket serverSocket =new ServerSocket(9999);
Socket socket =serverSocket.accept(); // 阻塞式方法
String ip =socket.getInetAddress().getHostAddress();
System.out.println("與" + ip + "建立連接");
BufferedReader br = newBufferedReader(new InputStreamReader(
socket.getInputStream()));
String line = null;
while((line =br.readLine())!=null){
System.out.println(ip+"發送來:"+line);
}
serverSocket.close();
System.out.println("TCP服務端關閉.....");
}
}
】
【
publicclass Client {
// TCP的客戶端
public static void main(String[] args)throws UnknownHostException,
IOException {
// TODO Auto-generated methodstub
System.out.println("TCP客戶端開啟.......");
Socket socket = newSocket("192.168.81.143", 9999);
// 將指定的文件上傳到服務器
// 一邊讀取文件數據,一邊向服務器端寫出數據
BufferedInputStream bis = newBufferedInputStream(new FileInputStream(
"g:\\extras下文件.rar"));
BufferedOutputStream bos =new BufferedOutputStream(socket.getOutputStream());
int b=0;
while((b=bis.read())!=-1){
bos.write(b);
}
bos.close();
bis.close();
socket.close();
System.out.println("TCP客戶端關閉.......");
}
}
publicclass Server {
public static void main(String[] args)throws IOException {
// TODO Auto-generated methodstub
System.out.println("tcp服務端開啟....");
ServerSocket serverSocket =new ServerSocket(9999);
Socket socket =serverSocket.accept();
String clientName =socket.getInetAddress().getHostName();
BufferedInputStream bis = newBufferedInputStream(
socket.getInputStream());
BufferedOutputStream bos =new BufferedOutputStream(
newFileOutputStream("g:\\" + clientName + ".rar"));
int b = 0;
while((b =bis.read()) !=-1){
bos.write(b);
}
bos.close();
bis.close();
System.out.println("tcp服務端關閉...");
}
}
】
【
publicclass Client {
public static void main(String[] args)throws UnknownHostException,
IOException {
// TODO Auto-generated methodstub
System.out.println("客戶端開啟./...");
Socket socket = newSocket("192.168.81.144", 6001);
System.out.println("成功與服務器建立連接....");
// 將鍵盤錄入的數據傳輸到服務器
BufferedReader br = newBufferedReader(new InputStreamReader(System.in));
BufferedWriter bw = newBufferedWriter(new OutputStreamWriter(
socket.getOutputStream()));
//讀一行寫一行
String line = null;?? //接收從鍵盤錄入的數據
while((line=br.readLine())!=null){
bw.write(line);
bw.newLine();
bw.flush();
}
bw.close();
br.close();
socket.close();
System.out.println("客戶端關閉.....");
}
}
//客戶端響應線程
publicclass ClientEchoThread extends Thread {
//客戶端對應的Socket對象(每個客戶端都有自己所對應的Socket對象)
private Socket socket;
private String ip;
public ClientEchoThread(Socket socket){
this.socket = socket;
ip =socket.getInetAddress().getHostAddress();
}
//在線程中執行客戶端的響應
@Override
public void run() {
System.out.println("建立與"+ip+"的連接");
BufferedReader br =null;
try {
br =newBufferedReader(new InputStreamReader(socket.getInputStream()));
//讀取來自客戶端的數據
String line = null;
while((line =br.readLine())!= null){
System.out.println(ip+":"+line);
}
} catch (IOException e) {
// TODOAuto-generated catch block
e.printStackTrace();
}finally{
if(br != null){
try {
br.close();
br= null;
} catch(IOException e) {
//TODO Auto-generated catch block
e.printStackTrace();
}
}
if(socket != null){
try {
socket.close();
socket= null;
} catch(IOException e) {
//TODO Auto-generated catch block
e.printStackTrace();
}
}
}
}
}
*開啟幾個線程?
*???? 有幾個客戶端就有幾個線程
*什么時候開線程?
*???? 一旦有了新的客戶端,就需要開啟一個新的線程
*線程中應該包含哪些代碼?
*???? 響應客戶端的請求
*/
publicclass Server {
public static void main(String[] args)throws IOException {
// TODO Auto-generated methodstub
System.out.println("服務端開啟....");
ServerSocket serverSocket = new ServerSocket(6001);
//接收來自客戶端的連接請求
//阻塞式方法,一旦有新的客戶端連接,就會返回一個客戶端對應的Socket對象
//作為客戶端,應該不停地去接受客戶端的請求
while(true){
Socket socket =serverSocket.accept();
newClientEchoThread(socket).start();
}
//???? ???serverSocket.close();
//???? ???System.out.println("服務端關閉....");
}
}
】