1. 程式人生 > >javaAPI_網絡編程基礎_網絡編程基礎2

javaAPI_網絡編程基礎_網絡編程基礎2

conn 解決方案 結果 println 適合 方法 tar ket sta


網絡編程基礎2

1.TCP協議

(1).實現步驟
A:創建發送端的Socket對象
這一步如果成功,就說明連接已經建立成功了。
B:獲取輸出流,寫數據
C:釋放資源

連接被拒絕。TCP協議一定要先看服務器。
java.net.ConnectException: Connection refused: connect

(2).客戶端
public static void main(String[] args) throws IOException {
// 創建發送端的Socket對象
// Socket(InetAddress address, int port)
// Socket(String host, int port)
// Socket s = new Socket(InetAddress.getByName("192.168.12.92"), 8888);
Socket s = new Socket("192.168.12.92", 8888);

// 獲取輸出流,寫數據
// public OutputStream getOutputStream()
OutputStream os = s.getOutputStream();
os.write("hello,tcp,我來了".getBytes());

// 釋放資源
s.close();
}

(3).服務器端接收數據步驟
A:創建接收端的Socket對象
B:監聽客戶端連接。返回一個對應的Socket對象
C:獲取輸入流,讀取數據顯示在控制臺
D:釋放資源


(4).代碼實現
public static void main(String[] args) throws IOException {
// 創建接收端的Socket對象
// ServerSocket(int port)
ServerSocket ss = new ServerSocket(8888);

// 監聽客戶端連接。返回一個對應的Socket對象
// public Socket accept()
Socket s = ss.accept(); // 偵聽並接受到此套接字的連接。此方法在連接傳入之前一直阻塞。

// 獲取輸入流,讀取數據顯示在控制臺
InputStream is = s.getInputStream();

byte[] bys = new byte[1024];
int len = is.read(bys); // 阻塞式方法
String str = new String(bys, 0, len);
//獲取IP地址
String ip = s.getInetAddress().getHostAddress();

System.out.println(ip + "---" + str);

// 釋放資源
s.close();
// ss.close(); //這個不應該關閉
}


(5).TCP協議接收發送數據圖解

技術分享圖片


2.TCP協議常用案例

(1).客戶端與服務器通信並且服務器端給客戶端反饋

//服務器端
public static void main(String[] args) throws IOException {
// 創建服務器Socket對象
ServerSocket ss = new ServerSocket(9999);

// 監聽客戶端的連接
Socket s = ss.accept(); // 阻塞

// 獲取輸入流
InputStream is = s.getInputStream();
byte[] bys = new byte[1024];
int len = is.read(bys); // 阻塞
String server = new String(bys, 0, len);
System.out.println("server:" + server);

// 獲取輸出流
OutputStream os = s.getOutputStream();
os.write("數據已經收到".getBytes());

// 釋放資源
s.close();
// ss.close();
}

//客戶端
public static void main(String[] args) throws IOException {
// 創建客戶端Socket對象
Socket s = new Socket("192.168.12.92", 9999);

// 獲取輸出流
OutputStream os = s.getOutputStream();
os.write("今天天氣很好,適合睡覺".getBytes());

// 獲取輸入流
InputStream is = s.getInputStream();
byte[] bys = new byte[1024];
int len = is.read(bys);// 阻塞
String client = new String(bys, 0, len);
System.out.println("client:" + client);

// 釋放資源
s.close();
}

(2).客戶端鍵盤錄入,服務器輸出到控制臺

//服務器端
public static void main(String[] args) throws IOException {
// 創建服務器Socket對象
ServerSocket ss = new ServerSocket(22222);

// 監聽客戶端連接
Socket s = ss.accept();

// 包裝通道內容的流
BufferedReader br = new BufferedReader(new InputStreamReader(
s.getInputStream()));
String line = null;
while ((line = br.readLine()) != null) {
System.out.println(line);
}

// br.close();
s.close();
// ss.close();
}

//客戶端
public static void main(String[] args) throws IOException {
// 創建客戶端Socket對象
Socket s = new Socket("192.168.12.92", 22222);

// 鍵盤錄入數據
BufferedReader br = new BufferedReader(new InputStreamReader(System.in));
// 把通道內的流給包裝一下
BufferedWriter bw = new BufferedWriter(new OutputStreamWriter(
s.getOutputStream()));

String line = null;
while ((line = br.readLine()) != null) {
// 鍵盤錄入數據要自定義結束標記
if ("886".equals(line)) {
break;
}
bw.write(line);
bw.newLine();
bw.flush();
}

// 釋放資源
// bw.close();
// br.close();
s.close();
}

(3).客戶端鍵盤錄入,服務器輸出文本文件

//服務器端
public static void main(String[] args) throws IOException {
// 創建服務器Socket對象
ServerSocket ss = new ServerSocket(23456);

// 監聽客戶端連接
Socket s = ss.accept();

// 封裝通道內的數據
BufferedReader br = new BufferedReader(new InputStreamReader(
s.getInputStream()));
// 封裝文本文件
BufferedWriter bw = new BufferedWriter(new FileWriter("a.txt"));

String line = null;
while ((line = br.readLine()) != null) {
bw.write(line);
bw.newLine();
bw.flush();
}

bw.close();
// br.close();
s.close();
// ss.close();
}

//客戶端
public static void main(String[] args) throws IOException {
// 創建客戶端Socket對象
Socket s = new Socket("192.168.12.92", 23456);

// 封裝鍵盤錄入
BufferedReader br = new BufferedReader(new InputStreamReader(System.in));
// 封裝通道內的數據
BufferedWriter bw = new BufferedWriter(new OutputStreamWriter(
s.getOutputStream()));

String line = null;
while ((line = br.readLine()) != null) {
if ("over".equals(line)) {
break;
}

bw.write(line);
bw.newLine();
bw.flush();
}

// bw.close();
// br.close();
s.close();
}


3.TCP協議常用案例2

(1).TCP協議上傳文本文件到服務器端

//客戶端
public static void main(String[] args) throws IOException {
// 創建客戶端Socket對象
Socket s = new Socket("192.168.12.92", 11111);

// 封裝文本文件
BufferedReader br = new BufferedReader(new FileReader(
"InetAddressDemo.java"));
// 封裝通道內流
BufferedWriter bw = new BufferedWriter(new OutputStreamWriter(
s.getOutputStream()));

String line = null;
while ((line = br.readLine()) != null) {
bw.write(line);
bw.newLine();
bw.flush();
}

// 釋放資源
br.close();
s.close();
}

//服務器端
public static void main(String[] args) throws IOException {
// 創建服務器端的Socket對象
ServerSocket ss = new ServerSocket(11111);

// 監聽客戶端連接
Socket s = ss.accept();

// 封裝通道內的流
BufferedReader br = new BufferedReader(new InputStreamReader(
s.getInputStream()));
// 封裝文本文件
BufferedWriter bw = new BufferedWriter(new FileWriter("Copy.java"));

String line = null;
while ((line = br.readLine()) != null) {
bw.write(line);
bw.newLine();
bw.flush();
}

bw.close();
s.close();
}


(2).TCP協議上傳文件並給反饋

註意問題:
按照我們正常的思路加入反饋信息,結果卻沒反應。為什麽呢?
讀取文本文件是可以以null作為結束信息的,但是呢,通道內是不能這樣結束信息的。
所以,服務器根本就不知道你結束了。而你還想服務器給你反饋。所以,就相互等待了。

如何解決呢?
A:在多寫一條數據,告訴服務器,讀取到這條數據說明我就結束,你也結束吧。
這樣做可以解決問題,但是不好。其實就是加了一個結束標識符
B:Socket對象提供了一種解決方案
public void shutdownOutput()

//客戶端
public static void main(String[] args) throws IOException {
// 創建客戶端Socket對象
Socket s = new Socket("192.168.12.92", 11111);

// 封裝文本文件
BufferedReader br = new BufferedReader(new FileReader(
"InetAddressDemo.java"));
// 封裝通道內流
BufferedWriter bw = new BufferedWriter(new OutputStreamWriter(
s.getOutputStream()));

String line = null;
while ((line = br.readLine()) != null) { // 阻塞
bw.write(line);
bw.newLine();
bw.flush();
}

//自定義一個結束標記
//bw.write("over");
//bw.newLine();
//bw.flush();

//Socket提供了一個終止,它會通知服務器你別等了,我沒有數據過來了
s.shutdownOutput();

// 接收反饋
BufferedReader brClient = new BufferedReader(new InputStreamReader(
s.getInputStream()));
String client = brClient.readLine(); // 阻塞
System.out.println(client);

// 釋放資源
br.close();
s.close();
}


//服務器端
public static void main(String[] args) throws IOException {
// 創建服務器端的Socket對象
ServerSocket ss = new ServerSocket(11111);

// 監聽客戶端連接
Socket s = ss.accept();// 阻塞

// 封裝通道內的流
BufferedReader br = new BufferedReader(new InputStreamReader(
s.getInputStream()));
// 封裝文本文件
BufferedWriter bw = new BufferedWriter(new FileWriter("Copy.java"));

String line = null;
while ((line = br.readLine()) != null) { // 阻塞
// if("over".equals(line)){
// break;
// }
bw.write(line);
bw.newLine();
bw.flush();
}

// 給出反饋
BufferedWriter bwServer = new BufferedWriter(new OutputStreamWriter(
s.getOutputStream()));
bwServer.write("文件上傳成功");
bwServer.newLine();
bwServer.flush();

// 釋放資源
bw.close();
s.close();
}

(3).上傳圖片到服務器並給反饋

//服務器端
public static void main(String[] args) throws IOException {
// 創建服務器Socket對象
ServerSocket ss = new ServerSocket(19191);

// 監聽客戶端連接
Socket s = ss.accept();

// 封裝通道內流
BufferedInputStream bis = new BufferedInputStream(s.getInputStream());
// 封裝圖片文件
BufferedOutputStream bos = new BufferedOutputStream(
new FileOutputStream("mn.jpg"));

byte[] bys = new byte[1024];
int len = 0;
while ((len = bis.read(bys)) != -1) {
bos.write(bys, 0, len);
bos.flush();
}

// 給一個反饋
OutputStream os = s.getOutputStream();
os.write("圖片上傳成功".getBytes());

bos.close();
s.close();
}

//客戶端反饋
public static void main(String[] args) throws IOException {
// 創建客戶端Socket對象
Socket s = new Socket("192.168.12.92", 19191);

// 封裝圖片文件
BufferedInputStream bis = new BufferedInputStream(new FileInputStream(
"林青霞.jpg"));
// 封裝通道內的流
BufferedOutputStream bos = new BufferedOutputStream(s.getOutputStream());

byte[] bys = new byte[1024];
int len = 0;
while ((len = bis.read(bys)) != -1) {
bos.write(bys, 0, len);
bos.flush();
}

s.shutdownOutput();

// 讀取反饋
InputStream is = s.getInputStream();
byte[] bys2 = new byte[1024];
int len2 = is.read(bys2);
String client = new String(bys2, 0, len2);
System.out.println(client);

// 釋放資源
bis.close();
s.close();
}


4.TCP協議多客戶端上傳文件到一個服務器上案例[*****]

//客戶端
public static void main(String[] args) throws IOException {
// 創建客戶端Socket對象
Socket s = new Socket("192.168.12.92", 11111);

// 封裝文本文件
// BufferedReader br = new BufferedReader(new FileReader(
// "InetAddressDemo.java"));
BufferedReader br = new BufferedReader(new FileReader(
"ReceiveDemo.java"));
// 封裝通道內流
BufferedWriter bw = new BufferedWriter(new OutputStreamWriter(
s.getOutputStream()));

String line = null;
while ((line = br.readLine()) != null) { // 阻塞
bw.write(line);
bw.newLine();
bw.flush();
}

// Socket提供了一個終止,它會通知服務器你別等了,我沒有數據過來了
s.shutdownOutput();

// 接收反饋
BufferedReader brClient = new BufferedReader(new InputStreamReader(
s.getInputStream()));
String client = brClient.readLine(); // 阻塞
System.out.println(client);

// 釋放資源
br.close();
s.close();
}

//服務器端
public class UploadServer {
public static void main(String[] args) throws IOException {
// 創建服務器Socket對象
ServerSocket ss = new ServerSocket(11111);

while (true) {
Socket s = ss.accept();
new Thread(new UserThread(s)).start();
}
}
}

//用戶線程端
public class UserThread implements Runnable {
private Socket s;

public UserThread(Socket s) {
this.s = s;
}

@Override
public void run() {
try {
// 封裝通道內的流
BufferedReader br = new BufferedReader(new InputStreamReader(
s.getInputStream()));
// 封裝文本文件
// BufferedWriter bw = new BufferedWriter(new
// FileWriter("Copy.java"));

// 為了防止名稱沖突
String newName = System.currentTimeMillis() + ".java";
BufferedWriter bw = new BufferedWriter(new FileWriter(newName));

String line = null;
while ((line = br.readLine()) != null) { // 阻塞
bw.write(line);
bw.newLine();
bw.flush();
}

// 給出反饋
BufferedWriter bwServer = new BufferedWriter(
new OutputStreamWriter(s.getOutputStream()));
bwServer.write("文件上傳成功");
bwServer.newLine();
bwServer.flush();

// 釋放資源
bw.close();
s.close();
} catch (IOException e) {
e.printStackTrace();
}
}
}

javaAPI_網絡編程基礎_網絡編程基礎2