Java 透過 Socket 完成所有網路底層通訊。Socket 是通訊管道,透過特定連接埠收發資料。Java Socket 分兩大類:
DatagramSocket:實作基本功能DatagramPacket:封裝資料包| 方法 | 說明 |
|---|---|
DatagramSocket() | 隨機繫結有效連接埠 |
DatagramSocket(int port) | 繫結指定連接埠 |
send(DatagramPacket p) | 發送資料包(目的地址已在封包中) |
receive(DatagramPacket p) | 接收資料包(線程安全) |
close() | 關閉 Socket |
不分 Client/Server,發送者為 Client,接收者為 Server。
DatagramPacket(byte[] buf, int length):接收用DatagramPacket(byte[] buf, int length, InetAddress addr, int port):發送用import java.io.*;
import java.net.*;
class FortuneServer extends Thread {
DatagramSocket serverSocket;
public FortuneServer() {
super("FortuneServer");
try {
serverSocket = new DatagramSocket(1114);
System.out.println("FortuneServer up and running...");
} catch (SocketException e) {
System.err.println("Exception: couldn't create datagram socket");
System.exit(1);
}
}
public static void main(String[] args) {
new FortuneServer().start();
}
public void run() {
if (serverSocket == null) return;
while (true) {
try {
byte[] data = new byte[256];
DatagramPacket packet = new DatagramPacket(data, data.length);
serverSocket.receive(packet);
InetAddress address = packet.getAddress();
int port = packet.getPort();
File inFile = new File("Fortunes.txt");
FileInputStream inStream = new FileInputStream(inFile);
if (inStream.read(data) <= 0)
System.err.println("Error: couldn't read fortunes");
packet = new DatagramPacket(data, data.length, address, port);
serverSocket.send(packet);
} catch (Exception e) {
System.err.println("Exception: " + e);
e.printStackTrace();
}
}
}
}
import java.io.*;
import java.net.*;
class FortuneClient {
public static void main(String[] args) {
FortuneClient client = new FortuneClient();
System.out.println(client.getMessage());
}
public String getMessage() {
try {
DatagramSocket socket = new DatagramSocket();
byte[] data = new byte[256];
DatagramPacket packet = new DatagramPacket(data, data.length,
InetAddress.getByName("127.0.0.1"), 1114);
socket.send(packet);
packet = new DatagramPacket(data, data.length);
socket.receive(packet);
String fortune = new String(packet.getData(), 0);
socket.close();
return fortune;
} catch (Exception e) {
System.err.println("Exception: " + e);
e.printStackTrace();
return null;
}
}
}
Socket(Client)與 ServerSocket(Server)。Socket(String host, int port) / Socket(InetAddress, int port):建立連線getInputStream()、getOutputStream():取得輸入/輸出串流close()連線建立後,操作方式與一般串流無異。
ServerSocket(int port) / ServerSocket(int port, int backlog) / ServerSocket(int port, int backlog, InetAddress bindAddr)accept():阻塞等待連線,回傳 Socket 物件close()三層設計:
package socketChat;
import java.io.BufferedReader;
public class Receiver extends Thread {
BufferedReader reader;
public Receiver(BufferedReader r) { reader = r; }
public void run() {
try {
while (true) {
String words = reader.readLine();
System.out.println("\r\n<<< " + words);
}
} catch (Exception e) { e.printStackTrace(); }
}
}
package socketChat;
import java.io.*;
public class Sender extends Thread {
PrintWriter writer;
public Sender(PrintWriter w) { writer = w; }
public void run() {
try {
BufferedReader console = new BufferedReader(new InputStreamReader(System.in));
while (true) {
String input = console.readLine();
writer.write(input + "\r\n");
writer.flush();
}
} catch (Exception e) { e.printStackTrace(); }
}
}
package socketChat;
import java.io.*;
import java.net.Socket;
public class SocketPerformer {
Socket socket;
public SocketPerformer(Socket s) { socket = s; }
public void execut() throws Exception {
BufferedReader socketReader = new BufferedReader(new InputStreamReader(socket.getInputStream()));
PrintWriter socketWriter = new PrintWriter(socket.getOutputStream());
System.out.println("connection built !");
new Receiver(socketReader).start();
new Sender(socketWriter).start();
}
}
package socketChat;
import java.net.*;
public class Server {
public static void main(String[] args) throws Exception {
ServerSocket server = new ServerSocket(30000, 5);
System.out.println("waiting incoming connection...");
Socket socket = server.accept();
System.out.println("a connection built! peer ip: " + socket.getInetAddress().getHostAddress());
new SocketPerformer(socket).execut();
server.close();
}
}
package socketChat;
import java.net.*;
public class Client {
public static void main(String[] args) throws Exception {
String ip = "127.0.0.1";
int port = 30000;
System.out.println("connecting to server: " + ip + " at port: " + port + " ...");
Socket soc = new Socket(ip, port);
new SocketPerformer(soc).execut();
}
}
final:常數、不可繼承類別、不可覆寫方法static:類別變數/方法instanceof:型別判斷getClass().getName():取得類別名稱java.lang、java.util、java.io、java.net、java.awt、java.appletnull、基本型別包裝類別(int→Integer)this()、super()、多類別單一檔案、介面與抽象類別差異String.copyValueOf()、new String(buf, offset, count)System.in (InputStream)、System.out/err (PrintStream)