1. 程式人生 > >Java網絡編程(一)

Java網絡編程(一)

第一個 jvm 本地 class 解決方案 *** ati 等待 輸入流

***********************第15章 socket編程(網絡編程)************************

網絡編程 != 網站編程


京東 淘寶 網站編程


網絡
QQ----------------->QQ


一.為什麽使用socket

當兩個應用程序之間需要交換數據的時候 需要使用socket


QQ聊天或者傳文件


二.什麽是socket


插座的意思


在編程中socket翻譯成套接字


一組API,功能是用來解決兩個應用程序之間傳輸數據的問題..


套接字= ip地址 + 端口號


ip地址: 用來唯一的標示一臺主機


端口號: 用來唯一的標示一個進程... 占2個字節 2的16次方 65536種可能

TCP 65536 UDP 65536

****************************************TCP和UDP的區別*************************

1.TCP

傳輸控制協議 面向連接的 安全的 有順序的 就像打電話 QQ視頻用的是TCP


三次握手


2.UDP

用戶數據報協議 面向無連接的 不安全的 沒有順序 就像寫信一樣 CS QQ聊天發信息都使用的是UDP


*************************************如何使用socket************************************

現在寫的程序 都要寫兩個應用程序


服務器端的插座 ServerSocket

客戶端的插座 Socket


先寫服務器端、再寫客戶端


Socket的優點: 只要用戶建立好socket連接以後, socket技術就把兩個應用程序之間傳輸數據的問題

給你簡化成I/O操作了....


1.服務器端

Server.java


package com.chapter15;

import java.io.IOException;
import java.net.ServerSocket;
import java.net.Socket;

//服務器端
public class Server {

public static void main(String[] args) {


//TCP socket
//一.建立socket連接

//1.新建ServerSocket
ServerSocket ss = null;
Socket socket = null;

try {
ss = new ServerSocket(8888);

socket = ss.accept();//阻塞式 傻傻的等待

System.out.println("有一個客戶端連接");
} catch (IOException e) {

System.out.println("端口號已被占用");
e.printStackTrace();
}

//二.I/O操作



//三.關閉socket連接
if(socket!=null){

try {
socket.close();
} catch (IOException e) {
System.out.println("關閉socket失敗");
e.printStackTrace();
}
}


}
}

2.客戶端

Client.java


package com.chapter15;

import java.io.IOException;
import java.net.Socket;
import java.net.UnknownHostException;

//客戶端
public class Client {

public static void main(String[] args) {

// 一.建立socket連接
// 2.申請連接 相當於打電話的撥號
// 第一個參數 是要連接的服務器的ip地址
// 現在我要連接的是本地這臺機器 localhost 127.0.0.1--->真實的本機ip
Socket socket = null;
try {
socket = new Socket("localhost", 8888);// 系統會為客戶端的插座
// 隨機分配一個1024以上的端口號
} catch (UnknownHostException e) {
System.out.println("主機不存在");
e.printStackTrace();
} catch (IOException e) {
System.out.println("連接失敗");
e.printStackTrace();
}

// 二.I/O操作

// 三.關閉socket連接
if (socket != null) {

try {
socket.close();
} catch (IOException e) {
System.out.println("關閉socket失敗");
e.printStackTrace();
}
}
}
}

***************************************常見錯誤*******************************************


常見錯誤1:


端口號已被占用
java.net.BindException: Address already in use: JVM_Bind
at java.net.DualStackPlainSocketImpl.bind0(Native Method)
at java.net.DualStackPlainSocketImpl.socketBind(DualStackPlainSocketImpl.java:106)
at java.net.AbstractPlainSocketImpl.bind(AbstractPlainSocketImpl.java:382)
at java.net.PlainSocketImpl.bind(PlainSocketImpl.java:190)
at java.net.ServerSocket.bind(ServerSocket.java:375)
at java.net.ServerSocket.<init>(ServerSocket.java:237)
at java.net.ServerSocket.<init>(ServerSocket.java:128)
at com.chapter15.Server.main(Server.java:21)


說明已經有應用程序使用8888端口了,解決方案 把之前8888端口上的進程殺掉即可... 殺占用內存小的那個javaw


*************************************演示文件傳輸功能***********************************

原理: 兩次復制

************************************模擬QQ 實現1對1聊天************************

需求1: 客戶端給服務器說一句話: 你好,服務器

ok


需求2: 服務器 給客戶端 回一句 : 你壞,客戶端

java.net.SocketException: Socket is closed
at java.net.Socket.getOutputStream(Socket.java:943)
at com.chapter15.演示一對一聊天.Server.main(Server.java:74)
Exception in thread "main" java.lang.NullPointerException
at com.chapter15.演示一對一聊天.Server.main(Server.java:82)


Socket被關閉了,而且socket並沒有關閉 是在最後關閉的...

*********************************發生如下四種情況的時候會關閉socket連接**************************


1. 調用socket對象的close()方法 主動關閉socket


2. 如果關閉了socket中的 輸入流或輸出流關閉了,socket也自動關閉了


3. 應用程序結束後,socket也會自動關閉


4. Socket socket = new Socket();

Socket socket = null;

socket = new Socket();

socket對象置空,或者是讓這個socket對象的引用 引用一個新的socket對象 原來的socket對象就會變成垃圾,被垃圾
回收器進行回收,內存回收完以後,socket會關閉

剛才是由於把輸入流或輸出流關了,所以socket自動關閉了,解決方案,在服務器回復完以後 再關輸入流

*************************改完以後雖然不報SocketException了,但是阻塞了**************************


原因是BufferedReader 只有碰到\n的時候 才認為真正讀進來數據,解決方案 說話的時候 都要加一個\n

Java網絡編程(一)