TCP通信
TCP通信-客戶端給服務端發送數據 -聊天室版本3-02
—————————-
案例:client可以重複向server發送數據,server在client下線後,給出響應數據.
分析:綜合了前面的案例,重複發送數據用到循環,服務端給出響應,
代碼實現如下:
package cn_socket通信_聊天室版本302;
import java.io.DataInputStream;
/*
* 客戶端發數據到服務端
* 1.Tcp傳輸,客戶端建立的過程.
* 創建tcp客戶端socket服務,使用的是socket對象
* 建議該對象一創建就明確目的地,要連接的主機.
* 2.如果連接建立成功,說明數據傳輸通道已建立。
* 該通道就是socket流,是底層建立好的。既然是流,說明這裏既有輸入,又有輸出。
* 想要輸入或輸出流對象,可以找Socket來獲取。
* 可以通過getOutputStream(),和getInputStream()來獲取兩個字節流
* 3.使用輸出流,將數據寫出。
* 4.關閉資源
*/
import java.io.DataOutputStream;
import java.io.IOException;
import java.net.Socket;
import java.net.UnknownHostException;
import java.util.Scanner;
/*
* 版本3-1:client可以重複向server發送數據,
* server在client下線後,給出響應數據
*/
public class Client {
public static void main(String[] args) throws UnknownHostException, IOException {
//創建客戶端Socket對象
//連接目標服務器的地址,localhost是目標服務器的地址,10086是目標服務器的端口
Socket socket = new Socket("localhost",10086);
Scanner sc = new Scanner(System.in);
//獲取Socket流中的輸出流,向服務器輸出消息,即發消息到服務器
DataOutputStream dos = new DataOutputStream(socket.getOutputStream());
while(true){
//發送數據的大小
String data = sc.nextLine();
byte[] bys=data.getBytes();
//寫數據-遵循TLD協議 1:文本數據 2:圖片數據 3:音頻數據
//發送的數據類型
dos.writeByte(1);
//發送數據長度
dos.writeInt(bys.length);
//寫要發送的數據 通常用了流之後要關閉的close()但是這裏不用
dos.write(bys);
dos.flush();//刷新
//判斷
if("886".equals(data)){
break;
}
}
//接收數據
//接收server的響應數據
DataInputStream dis = new DataInputStream(socket.getInputStream());
//通過socket對象獲取輸入流,要讀取服務端響應的數據
//接收數據類型
byte type=dis.readByte();
//接收數據長度
int len = dis.readInt();
//接收數據內容
byte[] bys= new byte[len];
dis.read(bys);
System.out.println(new String(bys,"utf-8"));
//斷開連接 客戶端下線 (所有的流也關閉)
sc.close();
socket.close();
}
}
package tedu.cn_socket通信_聊天室版本302;
/*
* 服務端接收客戶端發過來的數據,並打印在控制檯上。
* 建立tcp服務端的思路:
* 1.創建服務端Soket服務,通過ServerSocket對象
* 2.服務端必須對外提供一個端口,否則客戶端無法連接
* 3.獲取連接過來的客戶端對象
* 4.通過客戶端對象獲取socket流讀取客戶端發來的數據
* */
import java.io.DataInputStream;
import java.io.DataOutputStream;
import java.io.IOException;
import java.net.ServerSocket;
import java.net.Socket;
public class Server {
static ServerSocket ss;
static Socket socket;
//static byte type;
//UDP:發送端、接收端(無連接)
//TCP:客戶端、服務端(要連接)先啓動服務端,再啓動客戶端
public static void main(String[] args) throws IOException {
//創建服務端對象
ss = new ServerSocket(10086);
//監聽應用所在服務器的10086端口
//看有沒有客戶端連接過來,或者發送消息
//建立連接,獲取鏈接過來的客戶端對象
socket=ss.accept(); //接受客戶端請求,
//不停地接收此客戶端發送的數據
DataInputStream dis = new DataInputStream(socket.getInputStream());
while(true){
//通過socket對象獲取輸入流,要讀取客戶端發來的數據
//接收數據類型
byte type=dis.readByte();
//根據type判斷進行一些操作
//接收數據長度
int len = dis.readInt();
//接收數據內容
byte[] bys = new byte[len];
dis.read(bys);
String data =new String(bys);
System.out.println(data);
//"886" 意味着Client要下線
if("886".equals(data)){
System.out.println("此客戶端下線!");
break;
}
}
//向Client給出響應數據
DataOutputStream dos = new DataOutputStream(socket.getOutputStream());
//寫送數據類型
dos.writeByte(1);
//寫數據長度
String data ="接收完畢,您已下線";
byte[] content = data.getBytes("utf-8");
dos.writeInt(content.length);
//寫數據內容
dos.write(content);
dos.flush();
}
}
程序運行結果
先運行服務端,後運行客戶端