- Arguments: mailbox name (tên hịm thư)
a. Sử dụng Socket ở Client
- Dưới đây là một chương trình ngắn minh hoạ việc sử dụng Socket ở
Client. Trong ví dụ, client thiết lập một connection với Echo server (port = 7), ở
KILOB OB OO KS .CO M
một hàng từ standard input stream, gửi cho Echo server. Echo server nhận
được, gửi trả hàng này về lại client. Client đọc hàng này và xuất lại ra màn hình.
- Việc sử dụng Socket trong chương trình Client của phần mềm này cĩ
đơi chút phức tạp hơn nhưng những ý tưởng chính là hồn tồn giống nhau.
import java.io.*; import java.net.*;
public class EchoTest {
public static void main(String[] args) { Socket echoSocket = null;
DataOutputStream os = null; DataInputStream is = null;
DataInputStream stdIn = new DataInputStream(System.in); try {
echoSocket = new Socket("ResearchCC", 7);
os = new DataOutputStream(echoSocket.getOutputStream()); is = new DataInputStream(echoSocket.getInputStream()); } catch (UnknownHostException e) {
System.err.println("Don't know about host: ResearchCC"); } catch (IOException e) {
System.err.println("Couldn't get I/O for the connection to: ResearchCC");
}
if (echoSocket != null && os != null && is != null) { try {
String userInput;
while ((userInput = stdIn.readLine()) != null) { os.writeBytes(userInput); os.writeByte('\n'); System.out.println("echo: " + is.readLine()); } os.close(); is.close(); echoSocket.close(); } catch (IOException e) {
System.err.println("I/O failed on the connection to: ResearchCC"); }
} } }
Giải thích chương trình trên:
- Ba hàng sau trong khối try của phương thức main() buộc phải cĩ. Chúng thiết lập socket connetion giữa client-server và mở input, outputstream trên socket tạo ra:
echoSocket = new Socket("ResearchCC", 7);
os = new DataOutputStream(echoSocket.getOutputStream()); is = new DataInputStream(echoSocket.getInputStream());
KILOB OB OO KS .CO M
Hàng đầu tạo ra một đối tượng Socket, đặt tên là echoSocket. Socket constructor được sử dụng ởđây yêu cầu tên máy và port number mà ta muốn connect tới. Chương trình ví dụ dùng host name ResearchCC. Ðối số thứ hai là port number. Port 7 là port mà Echo server listen.
Hàng thứ hai và thứ ba mở một output stream và một input stream trên socket vừa thiết lập. EchoTest đơn thuần chỉ cần write tới output stream và read từ input stream để truyền dữ liệu với server thơng qua socket. Nếu bạn chưa quen với các stream trong Java, bạn cĩ thể xem thêm phần các Stream cũng trong đề tài này.
- Phần kế đọc từ standard input stream của EchoTest một hàng mỗi lần. EchoTest write ngay input text (theo sau bởi một newline character) tới output stream:
String userInput;
while ((userInput = stdIn.readLine()) != null) { os.writeBytes(userInput);
os.writeByte('\n');
System.out.println("echo: " + is.readLine()); }
- Hàng cuối trong vịng lặp while đọc một hàng từ input stream. Phương thức readLine() block cho tới khi server echo thơng tin trở về cho EchoTest. Khi readLine() return, EchoTest in hàng thơng tin ra standard output. Vịng lặp while tiếp tục-- EchoTest đọc input từ user, gửi nĩ cho Echo server, nhận trả
lời từ server, và hiển thị nĩ-- cho tới khi user đánh vào một end-of-input character.
- Khi user đánh vào một end-of-input character, vịng lặp while kết thúc, chương trình tiếp tục thực thi ba hàng kế:
os.close(); is.close();
echoSocket.close();
- Ba hàng code này đĩng các input, output stream, rồi đĩng socket connection tới server. Thứ tự thực hiện ởđây rất quan trọng, ta nên đĩng các stream kết nối với một socket trước khi đĩng chính socket đĩ.
- Nhìn chung, các bước cần tiến hành để dùng socket ở phía client như
sau:
1. Mở một socket.
2. Mở input stream và outputstream ứng vớ socket đĩ.
3. Read và write tới stream tuỳ thuộc vào nghi thức của server 4. Ðĩng các stream.
5. Ðĩng socket.
- Chỉ cĩ bước ba là khác nhau giữa các client, do dựa vào server. Các bước cịn lại hầu như giống nhau.
b. Sử dụng Socket ở Server
- Chương trình Server bắt đầu bằng việc tạo ra một instance của lớp ServerSocket để listen một port được đặc tả. Khi hiện thực một chương trình Server, ta nên chọn một port mà khơng được dành sẵn cho các dịch vụ khác:
KILOB OB OO KS .CO M
serverSocket = new ServerSocket(4444); } catch (IOException e) {
System.out.println("Could not listen on port: " + 4444 + ", " + e); System.exit(1);
}
- Bước kế tiếp, Server accept một connection request từ một client:
Socket clientSocket = null; try {
clientSocket = serverSocket.accept(); } catch (IOException e) {
System.out.println("Accept failed: " + 4444 + ", " + e); System.exit(1);
}
- Sau khi sinh ra socket ứng với client yêu cầu connect,server dựa vào socket và các input, output stream ứng với socket này để thực hiện việc read, write dữ liệu. Ðiều này hồn tồn giống như cách thức đã mơ tả ở phần sử
dụng soclet ở Client được mơ tả ở phần trên. Cụ thể là các việc sau: 1. Mở một input và output stream ứng với socket.
2. Read và write tới socket.
- Trong ví dụ, cĩ nhiều client đồng thời đưa ra các connection request với server tại port mà server listen (port 4444). Cĩ hai cách để giải quyết vấn
đề này:
1. Các connection request được xếp hàng, và Server phải accept các connection tuần tự
2. Phục vụ các connection request đồng thời bằng việc dùng các thread-- Mỗi thread xử lý một connection
Ví dụ đã chọn cách thứ hai để hiện thực vì nĩ hợp lý hơn: mọi user cần phải được xử lý bình đẳng như nhau.
Giải thuật cho phần này như sau:
while (true) {
accept a connection;
create a thread to deal with the client; end while
Thread được sinh ra sẽ read và write tới connection ứng với connection
đĩ khi cần thiết.