Java網路程式設計--多執行緒的Socket
阿新 • • 發佈:2019-01-04
首先,學好計算機網路知識真的很重要。雖然,學不好不會影響理解下面這個關於巨集觀講解,但是,學好了可以自己打漁吃,學不好就只能知道眼前有魚吃卻打不到漁。
在Java中網路程式有2種協議:TCP和UDP。
TCP
- 是可靠的連線。這個可靠的意思就是得有明確的連線物件才行,就像是打電話,撥打的號碼必須得在服務中有人接,這個網路會話才算是建立了。
UDP:
- 不可靠的連線。不可靠的意思就是不太確定這個會話最後是不是真的送達你要連線的物件那裡去了,就像是寄快遞,把快遞地址填上了,但是說不好半路會出點啥么蛾子,能不能安全送達不一定。
IP地址:
- 就是計算機的身份證。身份證號前六位數字是地址碼(可以知道是哪個省哪個城市哪個縣城),接著八位數字是出生日期碼,IP地址也是這樣的,它是由網路地址(確定是哪個網路)和主機地址(網路中的哪個主機)組成的。
- 本機地址: localhost等價於 127.0.0.1
下面的例子是基於TCP協議進行的。
public class Client {
public static void main(String[] args) throws Exception{
//開啟一個套接字,準備傳送請求
Socket socket = new Socket("localhost", 9996);//得先建立連線,就是所謂的TCP是建立可靠的連線
System.out.println("尊敬的VIP客戶,請求資料小分隊已準備好,請輸入您的請求:");
//向服務端傳送帶著客戶端請求的資料,這個請求資料是從鍵盤讀入的,傳送給服務端是以PrintWriter的形式包裝
PrintWriter out =new PrintWriter(socket.getOutputStream(),true);
//輸入流getInputStream(),單獨開一個執行緒在Receive類中完成接收伺服器發來的資料
Thread t = new Thread(new Receive(socket));
t.start();
Scanner scanner =new Scanner(System.in);//鍵盤輸入
while(scanner.hasNextLine()){
out.println(scanner.nextLine());//將從鍵盤輸入的資料傳送出去
}
}
}
public class Receive implements Runnable {
private Socket socket;
public Receive(Socket socket) {
this.socket=socket;
}
@Override
public void run() {
try {
Scanner scanner =new Scanner(socket.getInputStream());//接收資料
String str =null;
while(true){
str=scanner.nextLine();
System.out.println("伺服器說:"+str);//列印接收的資料
}
} catch (IOException e) {
e.printStackTrace();
}
}
}
public class Server {
public static void main(String[] args) throws Exception{
ServerSocket server = new ServerSocket(9996);//在埠9996開一個服務,監聽客戶端發來的請求,準備接收客戶端發來的請求資料
System.out.println("服務端準備完畢,隨時待命接收請求!");
Socket socket =server.accept();//只有當有客戶端請求並連線時,才回返回一個Socket物件,這個物件就是帶著客戶端請求的那個Socket物件
//建立一個PrintWriter的例項物件out來完成服務端向客戶端的輸出資料的任務,
PrintWriter out = new PrintWriter(socket.getOutputStream(),true);
//單獨開一個執行緒接收從客戶端過來的請求,在Receive1類中完成資料的接收
Thread t = new Thread(new Receive1(socket));
t.start();
/*一定要理解Socket是一個用於機器之間通訊的類*/
//傳送資料給客戶端
Scanner scanner = new Scanner(System.in);//鍵盤輸入服務端要發給客戶端的資料
while(scanner.hasNextLine()){
out.println(scanner.nextLine());//將鍵盤輸入的服務端要發給客戶端的資料封裝在PrintWriter類的物件中
}
}
}
public class Receive1 implements Runnable {
private Socket socket;
public Receive1(Socket socket) {
this.socket=socket;//在服務端接收客戶端發來的資料需要呼叫Receive1()這個方法,就會得到一個Socket物件,這個物件就是攜帶著客戶端請求的socket
}
@Override
public void run() {
try {
Scanner scanner=new Scanner(socket.getInputStream());//獲得客戶端從鍵盤接收的輸入流
String str = null;
while(true){
str=scanner.nextLine();
System.out.println("客戶端發來的資料:"+str);
}
} catch (IOException e) {
e.printStackTrace();
}//接收資料
}
}