27
Chương I: Cơ svmng ........................................................................ 1 1. Cu trúc mng ........................................................................................ 1 2. TCP ......................................................................................................... 2 3. UDP ........................................................................................................ 3 4. Các cng giao tiếp .................................................................................. 4 Chương II: Socket .................................................................................. 6 1. Tng quan vSocket .............................................................................. 6 1.1. Lch shình thành ............................................................................... 6 1.2. Định nghĩa .......................................................................................... 7 1.3. Nguyên lý hot động............................................................................ 7 Chương III. Htrlp trình socket trong Java ......................... 10 3.1. Ví dsdng giao thc hướng kết ni TCP: ................................... 11 3.2. Ví dsdng giao thc hướng kết ni TCP: ................................... 15 Phn 2. Xây dng ng dng ................................................................ 20 Chương 1. Phân tích thiết kế ............................................................ 20 1. Gii thiu .............................................................................................. 20 2. Phân tích hthng ................................................................................ 20 2.1 Mô hình chung ................................................................................. 20 2.2 Mô hình ca sdng ......................................................................... 21 2.3 Sơ đồ tun t.................................................................................... 21 2.4 Sơ đồ cng tác.................................................................................. 23 2.5 Biu đồ lp....................................................................................... 24 Chương 2. Xây dng chương trình................................................. 25 1. Xây dng chương trình cho Server ( Lp SocketServer.java) ............. 25 2. Xây dng chương trình cho Client ( Lp SocketClient.java) .............. 26

T5d.tai Lieu Socket Tiengviet

Embed Size (px)

Citation preview

Page 1: T5d.tai Lieu Socket Tiengviet

Chương I: Cơ sở về mạng ........................................................................1

1. Cấu trúc mạng ........................................................................................1

2. TCP.........................................................................................................2

3. UDP ........................................................................................................3

4. Các cổng giao tiếp ..................................................................................4

Chương II: Socket ..................................................................................6

1. Tổng quan về Socket ..............................................................................6

1.1. Lịch sử hình thành...............................................................................6

1.2. Định nghĩa ..........................................................................................7

1.3. Nguyên lý hoạt động............................................................................7

Chương III. Hỗ trợ lập trình socket trong Java.........................10

3.1. Ví dụ sử dụng giao thức hướng kết nối TCP: ...................................11

3.2. Ví dụ sử dụng giao thức hướng kết nối TCP: ...................................15

Phần 2. Xây dựng ứng dụng ................................................................20

Chương 1. Phân tích thiết kế ............................................................20

1. Giới thiệu..............................................................................................20

2. Phân tích hệ thống ................................................................................20

2.1 Mô hình chung.................................................................................20

2.2 Mô hình ca sử dụng .........................................................................21

2.3 Sơ đồ tuần tự ....................................................................................21

2.4 Sơ đồ cộng tác..................................................................................23

2.5 Biểu đồ lớp.......................................................................................24

Chương 2. Xây dựng chương trình.................................................25

1. Xây dựng chương trình cho Server ( Lớp SocketServer.java).............25

2. Xây dựng chương trình cho Client ( Lớp SocketClient.java) ..............26

Page 2: T5d.tai Lieu Socket Tiengviet

- 1 -

Phần 1: Cơ sở lý thuyết truyền thông máy tính

Trong phần này chúng ta sẽ xem xét một số khái niệm liên quan đến việc giao tiếp giữa các máy tính qua mạng: Cấu trúc của mạng, các giao thức …Tiếp đó chúng ta sẽ tập trung vào xem xét khái niệm lập trình socket nói chung cũng như lập trình socket trong Java nói riêng để có thể ứng dụng vào việc xây dựng chương trình trong phần hai của tiểu luận. Vì vậy cấu trúc của phần này đựợc chia thành 2 chương: Chương I: Cơ sở về mạng: Đề cập đến các khái niệm cơ sở về mạng phục vụ cho việc truyền thông máy tính. Chương II: Giao diện lập trình Socket: Đưa ra khái niệm, nguyên tắc hoạt động của socket, việc hỗ trợ socket trong các ngôn ngữ lập trình và trong java. Phần hỗ trợ lập trình Socket trong Java sẽ được giới thiệu chi tiết qua các ví dụ. Ở cuối chương này, để phục vụ cho việc xây dựng ứng dụng ở phần 2, chúng ta sẽ đề cập đến việc lập trình đa luồng trong java.

Chương I: Cơ sở về mạng

1. Cấu trúc mạng Chúng ta biết rằng các máy tính chạy trên mạng Internet giao tiếp với nhau thông qua hai giao thức TCP ( Transmission Control Protocol) và UDP ( User Datagram Protocol). Mô hình mạng Internet có thể đựợc mô tả trong sơ đồ sau:

Hình 1.1: Mô hình mạng Internet

(1) Tầng ứng dụng ( Application): Là các chương trình ứng dụng trên mạng. (2) Tầng giao vận ( Transport) : Có nhiệm vụ cơ bản là tryền tin giữa hai điểm

giao tiếp trên mạng. Tại tầng này người ta sử dụng giao thức TCP hoặc UDP.

(3) Tầng mạng( Network) : Có chức năng là tìm đường đi trên mạng, tại tầng này với mạng Internet người ta sử dụng giao thức IP.

(4) Tầng liên kết ( Link) : Thực hiện việc kết nối máy tính với môi trường mạng để có thể giao tiếp dữ liệu.

Page 3: T5d.tai Lieu Socket Tiengviet

- 2 -

Vì vậy khi bạn viết các chương trình giao tiếp với nhau qua mạng, tức là bạn đạng lập trình ở tầng ứng dụng. Thông thường người lập trình không cần phải viết lệnh để giao tiếp trực tiếp với các tầng bên dưới tầng ứng dụng mà thay vào đó họ sử dụng các hàm thư viện được ngôn ngữ lập trình hỗ trợ sẵn. Tuy nhiên để có thể lựa chọn hàm thư viện phù hợp chúng ta cần phải biết các giao thức được sử dụng ở tầng bên dưới.

2. TCP Định nghĩa: TCP ( Transmission Control Protocol) là một giao thức hướng kết nối, nó cung cấp một đường truyền dữ liệu tin cậy giữa hai máy tính. Tính tin cậy thể hiện ở việc nó đảm bảo dữ liệu được gửi sẽ đến được đích và theo đúng thứ tự như khi nó được gửi. Khi hai ứng dụng muốn giao tiếp với nhau một cách tin cậy, chúng sẽ tạo ra một đường kết nối giữa chúng và gửi dữ liệu thông qua đường này. Cách trao đổi dữ liệu này tương tự như cách chúng ta gọi điện thoại. Hãy lấy ví dụ khi bạn muốn nói chuyện với một người họ hàng tên là Beatrice sống tại Kentuky, bạn nhấc điện thoại lên và quay số của người họ hàng này, lúc đó một kết nối sẽ được tạo ra giữa điện thoại của bạn và của người họ hàng, sau đó bạn gửi và nhận dữ liệu ( dưới dạng âm thanh) bằng cách nói và nghe qua điện thoại của bạn. Toàn bộ việc thực hiện kết nối và truyền dữ liệu giữa hai máy điện thoại được thực hiện bởi công ty điện thoại thông qua các trạm và đường dây điện thoại, nhiệm vụ duy nhất của bạn là quay số để cung cấp cho nhà cung cấp dịch vụ điện thoại biết số điện thoại bạn muốn liên lạc. Giống như vậy, trong việc truyền dữ liệu qua mạng thì TCP đóng vai trò như nhà cung cấp dịch vụ điện thoại ở ví dụ trên, nó làm nhiệm vụ tạo kết nối và truyền dữ liệu giữa hai điểm giao tiếp để đảm bảo dữ liệu không bị mất và đến đích theo đúng trật tự như khi chúng được gửi. Tính tin cậy của đường truyền được thể hiện ở hai đặc điểm sau:

Mọi gói tin cần gửi sẽ đến được đích. Để làm điều này thì mỗi lần phía gửi gửi xong một gói tin nó sẽ chờ nhận một xác nhận từ bên nhận rằng đã nhận được gói tin. Nếu sau một khoảng thời gian mà phía gửi không nhận được thông tin xác nhận phản hồi thì nó sẽ phát lại gói tin. Việc phát lại sẽ được tiến hành cho đến khi việc truyền tin thành công, tuy nhiên sau một số lần phát lại max nào đó mà vẫn chưa thành công thì phía gửi có thể suy ra là không thể truyền tin được và sẽ dừng việc phát tin. Các gói tin sẽ được trình ứng dụng nhận được theo đúng thứ tự như chúng được gửi. Bởi các gói tin có thể được dẫn đi trên mạng theo nhiều con đường khác nhau trước khi tới đích nên thứ tự khi tới đích của chúng có thể không giống như khi chúng được phát. Do đó để đảm bảo có thể sắp xếp lại các gói tin ở phía nhận theo đúng thứ tự như khi chúng được gửi, giao thức TCP sẽ gắn vào mỗi gói tin một thông tin cho biết thứ tự của chúng trong cả khối tin chung được phát nhờ vậy bên nhận có thể sắp xếp lại các gói tin theo đúng thứ tự của chúng.

Page 4: T5d.tai Lieu Socket Tiengviet

- 3 -

Như vậy có thể thấy TCP cung cấp cho chúng ta một kênh truyền thông điểm-điểm phục vụ cho các ứng dụng đòi hỏi giao tiếp tin cậy như HTTP ( HyperText Tranfer Protocol), FTP ( File Tranfer Protocol), Telnet… Các ứng dụng này đòi hỏi một kênh giao tiếp tin cậy bởi thứ tự của dữ liệu được gửi và nhận là yếu tố quyết định đến sự thành công hay thất bại của chúng. Hãy lấy ví dụng khi HTTP được sử dụng để đọc thông tin từ một điạ chỉ URL, dữ liệu phải được nhận theo đúng thứ tự mà chúng được gửi nếu không thứ mà bạn nhận được có thể là một trang HTML với nội dung lộn xộn hoặc một file zip bị lỗi và không thể giải nén…

3. UDP Định nghĩa: UDP ( User Datagram Protocol) là giao thức không hướng kết nối, nó gửi các gói dữ liệu độc lập gọi là datagram từ máy tính này đến máy tính khác mà không đảm bảo việc dữ liệu sẽ tới đích. Ở phần trước chúng ta đã thấy trong giao thức TCP khi hai chương trình muốn giao tiếp với nhau qua mạng chúng tạo ra một kết nối liên kết hai ứng dụng và trao đổi dữ liệu qua kết nối đó. Trái lại ở giao thức UDP khi hai ứng dụng muốn giao tiếp với nhau chúng không tạo ra kết nối mà chỉ đơn thuần gửi các gói tin một cách độc lập từ máy này tới máy khác. Các gói tin như vậy gọi là các datagram. Việc gửi các gói tin như vậy tương tự như việc chúng ta gửi thư qua đường bưu điện: Các bức thư bạn gửi độc lập với nhau, thứ tự các lá thư là không quan trọng và không có gì đảm bảo là thư sẽ đến đươc đích. Trong truyền thông bằng UDP thì các datagram giống như các lá thư, chúng chứa thông tin cần gửi đi cùng thông tin về địa chỉ đích mà chúng phải đến, tuy nhiên chúng khác với các lá thư ở một điểm là nếu như trong việc gửi thư, nếu lá thư của bạn không đến được đích thì nó sẽ được gửi trả lại nơi gửi nếu trên lá thư đó bạn có đề điạ chỉ gửi còn UDP sẽ không thông báo gì cho phía gửi về việc lá thư đó có tới được đích hay không. Vậy nếu UDP là một giao thức không đảm bảo giao tiếp tin cậy thì tại sao người ta lại dùng chúng. Điều đó là bởi nếu như giao thức TCP đảm bảo một kết nối tin cậy giữa các ứng dụng thì chúng cũng đòi hỏi nhiều thời gian để truyền tin do chúng phải kiểm tra các header của các gói tin để đảm bảo thứ tự của các gói tin cũng như để phát lại các gói tin không đến được đích do đó trong một số trường hợp thì điều này là không cần thiết. Dưới đây là một số trường hợp trong đó giao thức không hướng kết nối là thích hợp hơn so với giao thức hướng kết nối: Khi chỉ một gói dữ liệu cần truyền đi và việc có đến được đích hay không là không quan trọng, sử dụng giao thức UDP sẽ loại bỏ được các thủ tục tạo và hủy kết nối. So sánh một chút chúng ta sẽ thấy giao thức hướng kết nối TCP phải dùng đến 7 gói tin để gửi một gói tin do nó cần phát và nhận các gói tin yêu cầu và chấp nhận kết nối cũng như các gói tin yêu cầu và xác nhận việc hủy kết nối, trong khi đó giao thức không hướng kết nối UDP chỉ sử dụng duy nhất một gói tin chính là gói tin chứa dữ liệu cần chuyể đi.

Page 5: T5d.tai Lieu Socket Tiengviet

- 4 -

Chúng ta hãy lấy ví dụ về một server đồng hồ, nhiệm vụ của nó là gửi thời gian hiện tại của nó cho các ứng dụng trên client khi có yêu cầu. Nếu gói tin chứa thời gian bị thất lạc trên đường truyền và không tới được đích thì client cũng sẽ không đòi hỏi server phải gửi lại gói tin đó bởi khi gói tin đó được phát lại lần hai và tới được client thì thông tin thời gian chứa trong nó đã không còn đúng nữa. Nếu client tạo ra hai yêu cầu và nhận được các gói tin trả lời không theo đúng thứ tự mà server đã gửi thì client cũng không gặp phải vấn đề gì bởi nó hoàn toàn có thể suy ra được rằng các gói đã không được chuyển đến đúng thứ tự bằng cách tính thời gian được chứa trong các gói. Trong trường hợp này tính tin cậy của TCP là không cần thiết bởi nó làm giảm hiệu xuất và có thể cản trở hoạt động của server. Trường hợp thứ hai chúng ta xem xét việc sử dụng giao thức UDP là các ứng dụng đòi hỏi chặt chẽ về thời như các ứng dụng nghe audio thời gian thực . Trong trường hợp này việc hướng tới một kênh giao tiếp tin cậy không phải là ưu điểm mà ngược lại đó là một nhược điểm bởi nếu việc phải chờ cho khi một gói tin bị mất được nhận có thể gây ra những tác động dễ nhận thấy hoặc khiến chương trình phải tạm dừng. Với các ứng dụng này giao thức không hướng kết nối đã được phát triển và chúng làm việc tốt hơn hẳn. Chúng ta có thể tham khảo ứng dụng RealAudio, trong đó người ta sử dụng một giao thức chạy phía trên giao thức không hướng kết nối để truyền các dữ liệu âm thanh qua mạng. Một trường hợp khác mà chúng ta có thể thấy xem xét việc sử dụng giao thức không hướng kết nối là khi chúng ta cần kiểm tra tình trạng của kết nối mạng, điều này các bạn có thể thực hiện trong hệ điều hành Window, Unix với câu lệnh Ping. Để làm việc này bạn sử dụng câu lệnh Ping trên máy thứ nhất và cung cấp cho nó địa chỉ của máy thứ hai mà bạn cần kiểm tra kết nối. Khi đó câu lênh Ping sẽ phát đi gói tin kiểm tra tới máy thứ hai, nếu máy thứ hai nhận được gói tin kiểm tra nó sẽ phát lại gói tin trả lời, khi đó thông qua việc có nhận được gói tin từ máy thứ hai hay không câu lênh Ping có thể xác định được tình trạng kết nối giữa hai máy. Việc kiểm tra có thể tiến hành nhiều lần để đảm bảo độ chính xác của kết quả. Như vậy ở đây thông tin ma câu lệnh Ping cần biết là về các gói tin không đến đươc đích và các gói tin không đến đúng thứ tự để có thể xác định được kết nối là tốt hay xấu. Do đó nếu sử dụng một kênh tin cậy ở đây thì sẽ không thể có căn cứ để xác định chất lượng của kết nối bởi kênh tin cậy sẽ đảm bảo các gói tin luôn đến đích và đến đúng thứ tự thông qua các cơ chế kiểm tra và phát lại.

4. Các cổng giao tiếp Định nghĩa: Cổng là một cơ chế cho phép dữ liệu được truyền đến đúng ứng dụng đang chạy trên máy tính. Chúng ta biết rằng mỗi máy tính chỉ có một kết nối vật lý với mạng, tất cả các dữ liệu cần truyền cho máy tính khác sẽ được mang đi bởi kết nối này. Tuy nhiên chúng ta cũng lại thấy rằng trên mỗi máy tính không chỉ có một mà có thể có nhiều ứng dụng ( chương trình) cùng chạy và cùng có nhu cầu giao tiếp qua mạng

Page 6: T5d.tai Lieu Socket Tiengviet

- 5 -

do đó dữ liệu máy tính nhận được thông qua kết nối với mạng cần phải được chuyển đến đúng ứng dụng cần nó vì vậy máy tính cần phải biết dữ liệu mà nó nhận được được phía gửi hi vọng chuyển đến ứng dung nào. Việc này được thực hiện thông qua việc sử dụng các cổng:

• Mỗi ứng dụng chạy trên máy tính sẽ được gắn với một cổng logic, đó là một số 16 bit. Các cổng có giá trị từ 0 đến 65 535 ( 216-1), trong đó các cổng từ 0 tới 1023 bị hạn chế, chúng chủ yếu được sử dụng cho các dịch vụ phổ biến như HTTP, FTP… , các cổng còn lại được sử dụng cho các ứng dụng của người dùng.

• Dữ liệu truyền qua mạng Internet chứa trong nó thông tin để xác định định danh và cổng trên máy tính mà nó cần đến. Định danh của mỗi máy tính được xác định bằng một địa chia IP có chiều dài 32 bit.

Việc gán một ứng dụng với một cổng có thể được thực hiện bởi chương trình hoặc bởi hệ điều hành tùy theo mục đích sử dụng của ứng dụng. Điều này chúng ta sẽ xem xét cụ thể trong phần lập trình socket ở chương sau.

Page 7: T5d.tai Lieu Socket Tiengviet

- 6 -

Chương II: Socket 1. Tổng quan về Socket

1.1. Lịch sử hình thành Khái niệm Socket xuất hiện lần đầu tiên vào khoảng năm 1980 tại trường

đại học Berkeley Mỹ. Đó là một chương trình được thiết kế để giúp máy tính nối mạng ở khắp mọi nơi có thể trao đổi thông tin với nhau. Lúc đầu nó được sử dụng trên các máy Unix và có tên gọi là Berkeley Socket Interface.

Tiếp đó cùng với sự phát triển của các ứng dụng mạng, Socket được hỗ trợ trong nhiều ngôn ngữ lập trình và chạy trên nhiều nền tảng hệ điều hành khác nhau. Ví dụ như WinSock dùng cho các ứng dụng của Microsoft, Socket++ dùng cho các lập trình viên sử dụng Unix…

Một câu hỏi đặt ra là tại sao chúng ta lại sử dụng Socket trong truyền thông giữa các máy tính. Để trả lời câu hỏi này chúng ta phải quay lại thời điểm trước khi Socket ra đời:

Trong thời kì này trên hệ thống Unix việc vào/ra dữ liệu được thực hiện theo mô hình 3 bước Open-Read/Write-Close. Để thực hiện việc vào ra dữ liệu trước hết chương trình phải tạo ra một kết nối với tài nguyên mà nó muốn giao tiếp ( tài nguyên này có thể là bàn phím, bộ nhớ trong, file ..), sau khi kết nối đã được thực hiện, chương trình có thể trao đổi dữ liệu thông qua các thao tác Read-đưa dữ liệu từ tài nguyên đã kết nối vào chương trình để xử lý hoặc Write-đưa dữ liệu đã xử lý từ chương trình ra tài nguyên. Một ví dụ điển hình cho kiểu vào/ra này là thao tác với file dữ liệu mà chúng ta khá quen thuộc trong các ngôn ngữ lập trình: Khi người lập trình muốn thao tác với một file dữ liệu họ tiến hành như sau:

Mở file cần sử dụng với các quyền thích hợp trên đó Thực hiện việc đọc dữ liệu từ file để xử lý hay đưa dữ liệu đã xử lý để ghi vào file. Đóng file sau khi đã sử dụng xong.

Khi việc trao đổi dữ liệu giữa các chương trình và kết nối mạng được đưa vào hệ thống Unix người ta mong muốn việc trao đổi dữ liệu giữa các chương trình cũng sẽ được thực hiện theo mô hình 3 bước của vào/ra dữ liệu nhằm tránh cho người lập trình những khó khăn khi giao tiếp với các tầng bên dưới tầng ứng dụng. Để làm được điều đó, Socket được sử dụng. Khi hai chương trình muốn giao tiếp với nhau, mỗi chương trình sẽ tạo ra một Socket, chúng đóng vai trò là các điểm cuối trong một kết nối và thực hiện việc trao đổi thông tin giữa hai chương trình. Đối với người lập trình, Socket được xem như một tài nguyên hệ thống mà chương trình cần giao tiếp nên chương trình có thể thực hiện giao tiếp với Socket theo mô hình 3 bước giống như việc vào/ra dữ liệu. Như vậy sự ra đời của socket gắn liền với nhu cầu truyền thông máy tính. Sau đây chúng ta sẽ đưa ra định nghĩa cụ thể về socket.

Page 8: T5d.tai Lieu Socket Tiengviet

- 7 -

1.2. Định nghĩa Có nhiều định nghĩa khác nhau về socket tùy theo các nhìn của người sử

dụng: Một cách tổng quát nhất có thể định nghĩa Một Socket là một điểm cuối

trong một kết nối giữa hai chương trình đang chạy trên mạng. Nhìn trên quan điểm của người phát triển ứng dụng người ta có thể định

nghĩa Socket là một phương pháp để thiết lập kết nối truyền thông giữa một chương trình yêu cầu dịch vụ ( được gán nhãn là Client) và một chương trình cung cấp dịch vụ ( được gán nhãn là Server) trên mạng hoặc trên cùng một máy tính.

Đối với người lập trình, họ nhìn nhận Socket như một giao diện nằm giữa tầng ứng dụng và tầng khác trong mô hình mạng OSI có nhiệm vụ thực hiện việc giao tiếp giữa chương trình ứng dụng với các tầng bên dưới của mạng.

Hình 2.1: Mô hình OSI rút gọn

Tuy nhiên, các lập trình viên hiện nay gần như luôn luôn bị ngăn cản tạo

socket riêng bằng cách thủ công bởi dù bạn dùng Java, serlet, hay CGI,PHP,…, có thể bạn sẽ không bao giờ mở được cổng một cách tường minh. Thay vào đó các lập trình viên sử dụng thư viện socket được hỗ trợ sẵn bởi các ngôn ngữ lập trình. Như vậy các socket vẫn tồn tại để kết nối các ứng dụng của người dùng, nhưng các chi tiết của socket được ẩn trong những lớp sâu hơn để mọi người không phải động chạm đến.

1.3. Nguyên lý hoạt động Trong phần trên chúng ta đã thấy khi hai ứng dụng muốn trao đổi dữ liệu qua mạng chúng sẽ tạo ra ở mỗi phía một socket và trao đổi dữ liệu bằng cách đọc và ghi từ socket. Để hiểu rõ cách thức socket trao đổi dữ liệu chúng ta hãy xem xét nguyên lý hoạt động của chúng. Trước hết chúng ta hãy xem làm thế nào các socket có thể xác định đựợc nhau. Khi một chương trình tạo ra một socket, một định danh dạng số sẽ được gán cho

Transport (TCP, UDP,..)

Network (IP,...)

Link

Application (HTTP,ftp,telnet,…)

SOCKET

Page 9: T5d.tai Lieu Socket Tiengviet

- 8 -

socket, định danh này chính là cổng mà chúng ta đã thảo luận trong phần cơ sở về mạng ở chương 1 phần 1. Việc gán số cổng này cho socket có thể được thực hiện bởi chương trình hoặc bởi hệ điều hành tùy theo cách socket được sử dụng như thế nào. Trong mỗi gói tin mà socket gửi đi có chứa hai thông tin để xác định đích đến của gói tin:

Một địa chỉ mạng để xác định hệ thống sẽ nhận gói tin. Một số định danh cổng để nói cho hệ thống đích biết socket nào trên nó sẽ

nhận dữ liệu. Nhờ hai thông tin này mà gói tin có thể đến được đúng máy tính chứa socket mà nó cần đến ( nhờ địa chỉ mạng) và được phân phối đến đúng socket đích ( nhờ địa chỉ cổng của socket đích). Bởi dưới góc độ lập trình các socket thường làm việc theo cặp, một socket đóng vai trò làm client còn các socket khác đóng vai trò như một server. Socket phía server xác định một cổng cho giao tiếp mạng, sau đó chờ nghe dữ liệu mà client gửi tới nó bằng client socket. Do đó các cổng cho server socket phải được biết bởi các chương trình client. Ví dụ server FTP sử dụng một socket để nghe tại cổng 21 do đó nếu một chương trình client muốn giao tiếp với server FTP nó cần phải kết nối đến socket đang nghe tại cổng 21. Như vậy cổng của socket phía server được xác định bởi chương trình, ngược lại cổng cho client socket được xác định bởi hệ điều hành. Khi một socket phía client gửi một gói tin tới socket phía server thì trong gói tin đã có chứa thông tin về địa chỉ của hệ thống client và cổng của socket phía client nên server hoàn toàn có thể gửi thông tin phản hồi cho client. Chúng ta có thể khái quát quá trình trao đổi dữ liệu thông qua các socket như sau:

1. Chương trình phía Server tạo ra một socket, socket này được chương trình gắn với một cổng trên server. Sau khi đựợc tạo ra socket này ( mà từ nay ta sẽ gọi là socket phía server) sẽ chờ nghe yêu cầu từ phía client.

2. Khi chương trình phía Client cần kết nối với một Server, nó cũng tạo ra một socket, socket này cũng được hệ điều hành gắn với một cổng. Chương trình Client sẽ cung cấp cho Socket của nó ( mà từ nay ta sẽ gọi là Socket phía Client) điạ chỉ mạng và cổng của Socket phía Server và yêu cầu thực hiện kết nối ( nếu chương trình định sử dụng giao thức hướng kết nối) hoặc truyền dữ liệu ( nếu chương trình sử dụng giao thức không hướng kết nối).

3. Chương trình phía Server và chương trình phía Client trao đổi dữ liệu với nhau bằng cách đọc từ Socket hoặc ghi vào Socket của minh. Các socket ở hai phía nhận dữ liệu từ ứng dụng và đóng gói để gửi đi hoặc nhận các dữ liệu được gửi đến và chuyển cho chương trình ứng dụng bởi socket ở cả hai phía đều biết được địa chỉ mạng và điạ chỉ cổng của nhau.

Ở bước thứ hai chúng ta thấy chương trình ứng dụng phải lựa chọn giao thức mà nó định sử dụng để trao đổi dữ liệu. Tùy theo việc chúng ta sử dụng giao thức nào ( TCP hay UDP) mà cách thức xử lý trước yêu cầu của client có thể khác. Sau

Page 10: T5d.tai Lieu Socket Tiengviet

- 9 -

đây chúng ta sẽ xem xét chi tiết các thức trao đổi dữ liệu của Socket ứng với từng loại giao thức.

1.3.1. Socket hỗ trợ TCP

a. Ở phía Server: Khi một ứng dụng trên server hoạt động nó sẽ tạo ra một socket và đăng ký với server một cổng ứng dụng và chờ đợi yêu cầu kết nối từ phía client qua cổng này.

Hình 2.2: Client gửi yêu cầu đến Server

b. Ở phía client: Nó biết địa chỉ của máy trên đó server đang chạy và cổng và server đang chờ nghe yêu cầu. Do đó khi muốn kết nối đến Server, nó cũng tạo ra một socket chứa địa chỉ máy client và cổng của ứng dụng trên máy client đồng thời client sẽ cung cấp cho socket của nó địa chỉ và cổng của Server mà nó cần kết nối và yêu cầu Socket thực hiện kết nối. Khi Server nhận được yêu cầu kết nối từ Client, nếu nó chấp nhận thì server sẽ sinh ra một socket mới được gắn với một cổng khác với cổng mà nó đang nghe yêu cầu. Sở dĩ server làm như vậy bởi nó cần cổng cũ để tiếp tục nghe yêu cầu từ phía client trong khi vẫn cần một kết nối với client.

Hình 2.3: Server chấp nhận yêu cầu và tạo một socket để phục vụ client

Sau đó chương trình ứng dụng phía Server sẽ gửi thông báo chấp nhận kết nối cho Client cùng thông tin về địa chỉ cổng mới của socket mà nó dành cho Client. c. Quay lại phía client, nếu kết nối được chấp nhận nghĩa là socket của nó đã được tạo ra thành công và nó có thể sử dụng socket để giao tiếp với server bằng cách viết và ghi tới socket theo cách giao tiếp với một tài nguyên trên máy tính thông thường.

1.3.2. Socket hỗ trợ UDP

a.Ở phía Server: Khi một ứng dụng trên server hoạt động nó sẽ tạo ra một socket và đăng ký với server một cổng ứng dụng và chờ đợi yêu cầu kết nối từ phía client qua cổng này. b. Ở phía client: Nó biết địa chỉ của máy trên đó server đang chạy và cổng và server đang chờ nghe yêu cầu. Do đó khi muốn giao tiếp với Server, nó cũng tạo

Page 11: T5d.tai Lieu Socket Tiengviet

- 10 -

ra một socket chứa địa chỉ máy client và cổng của ứng dụng trên máy client đồng thời client sẽ cung cấp cho socket của nó địa chỉ và cổng của Server mà nó cần kết nối. Khi client muốn gửi tin đến Server nó sẽ chuyển dữ liệu cho socket của minh, socket này sẽ chuyển thẳng gói tin mà client muốn gửi tới server dưới dạng một datagram có chứa địa chỉ máy server và cổng mà server đang chờ nghe yêu cầu. Như vậy không hề có môt kết nối nào được thực hiện giữa client với server và server cũng không cần tạo ra một socket khác để kết nối với client thay vào đó server dùng ngay cổng ban đầu để trao đổi dữ liệu.

Chương III. Hỗ trợ lập trình socket trong Java Trong chương này chúng ta sẽ xem xét các lớp được java xây dựng sẵn để hỗ trợ lập trình mạng nói chung và hỗ trợ lập trình Socket nói riêng. Phần cuối của chương chúng ta sẽ xem các ví dụ minh họa việc sử dụng các lớp này. Trong ngôn ngữ lập trình Java, các lớp hỗ trợ lập trình mạng được chứa trong gói java.net. Dưới đây cấu trúc của gói của gói:

Hình 3.1:Cấu trúc của gói java.net

InetAddress : Biểu diễn địa chỉ của Internet, trong đó quan trọng nhất là

hai phương thức getHostName() và getAddress() dùng để chuyển đối giữa địa chỉ IP và tên Host. ServerSocket : Biểu diễn cho socket phía server

Page 12: T5d.tai Lieu Socket Tiengviet

- 11 -

Socket: Biểu diễn cho Socket phía client với điều kiện giao thức tầng dưới là TCP DatagramSocket: Biểu diễn cho Datagram Socket, một dạng của giao thức

kết nối dùng UDP. DatagramPacket: Biểu diễn cho Datagram Packet, gói dữ liệu trong đó mô

tả chi tiết nơi nhận và dữ liệu cần gửi. SocketImpl: Để cài đặt cho ServerSocket và Socket SocketImplFactory: Một thể hiện của SocketImpl

Đối với lập trình socket, ở chương trước chúng ta đã biết rằng có hai loại socket là socket hỗ trợ TCP và socket hỗ trợ UDP. Trong Java hỗ trợ cả hai loại socket này với các lớp khác nhau theo bảng sau:

Giao thức Client Server Hướng kết nối ( TCP) Socket ServerSocket

Không hướng kết nối ( UDP) DatagramSocket DatagramSocke

Bảng 3.1: Các lớp hỗ trợ giao thức trong Java Sau đây chúng ta sẽ xem các lớp này được sử dụng như thế nào qua các ví dụ:

3.1. Ví dụ sử dụng giao thức hướng kết nối TCP: Chúng ta sẽ xây dựng một ví dụ đơn giản trong đó gồm chương trình phía clien và chương trình phía server hoạt động theo nguyên tắc sau: Khi chương trình client chạy, nó sẽ chờ người dùng nhập vào một dòng văn bản. Sau khi người dùng nhập xong, dòng văn bản này sẽ được gửi tới server. Tại chương trình phía server, nhiệm vụ của nó là nhận dữ liệu liệu từ client rồi gửi ngược dữ liệu lại phía client. Chúng ta sẽ xây dựng hai lớp EchoServer: Chương trình phía server EchoClient: Chương trình phía client

EchoServer sẽ tạo ra một socket được gắn với cổng số 7 trên máy tính. EchoClient tạo ra một socket và kết nối tới EchoServer, nó đọc thông tin vào từ người sử dụng trong luồng dữ liệu vào sau đó gửi dữ liệu này tới EchoServer bằng cách viết dữ liệu này vào socket. EchoServer sẽ nhận dữ liệu từ EchoClient bằng cách đọc dữ liệu từ socket sau đó gửi lại dữ liệu này cho EchoClient bằng cách viết dữ liệu vào socket. EchoClient nhận

Page 13: T5d.tai Lieu Socket Tiengviet

- 12 -

được dữ liệu phản hồi từ Server bằng cách đọc socket của nó, sau đó nó hiển thị nội dung ra màn hình.

Lớp EchoServer import java.io.*; import java.net.*; public class EchoServer1 { public static void main(String[] args) throws IOException { ServerSocket serverSocket = null; Socket clientSocket = null; try { serverSocket = new ServerSocket(7); } catch (IOException e) { System.err.println("Khong nghe duoc o cong so : 7."); System.exit(1); } try { System.out.println("Dang cho ket noi"); clientSocket= serverSocket.accept(); System.out.println("Ket noi thanh cong"); } catch (IOException e) { System.err.println("Accept failed."); System.exit(1); } PrintWriter out = new PrintWriter(clientSocket.getOutputStream(), true); BufferedReader in = new BufferedReader( new InputStreamReader(clientSocket.getInputStream())); String inputLine, outputLine; while ((inputLine = in.readLine()) != null) { outputLine = inputLine;

Page 14: T5d.tai Lieu Socket Tiengviet

- 13 -

out.println(outputLine); System.out.println("Client:"+inputLine); if (outputLine.equals("Bye.")) break; } out.close(); in.close(); clientSocket.close(); serverSocket.close(); } }

Tiến trình hoạt động như sau:

Tạo socket gắn với cổng số 7 của máy để chờ nhận kết nối từ phía client serverSocket = new ServerSocket(7);

Tạo socket phụ để phục vụ giao tiếp với client nhằm dành socket chính cho các yêu cầu kết nối khác

clientSocket= serverSocket.accept(); Lấy dữ liệu từ EchoClient bằng cách đọc từ socket mà nó dành để phục vụ

client BufferedReader in = new BufferedReader( new InputStreamReader(clientSocket.getInputStream()));

Trả lại dữ liệu đấy cho EchoClient PrintWriter out = new PrintWriter(clientSocket.getOutputStream(), true); while ((inputLine = in.readLine()) != null) { outputLine = inputLine; out.println(outputLine); System.out.println("Client:"+inputLine); if (outputLine.equals("Bye.")) break; }

Page 15: T5d.tai Lieu Socket Tiengviet

- 14 -

Lớp EchoClient import java.io.*; import java.net.*; public class EchoClient { public static void main(String[] args) throws IOException { Socket echoSocket = null; PrintWriter out = null; BufferedReader in = null; try { echoSocket = new Socket("localhost", 7); out = new PrintWriter(echoSocket.getOutputStream(), true); in = new BufferedReader(new InputStreamReader( echoSocket.getInputStream())); } catch (UnknownHostException e) { System.err.println("Don't know about host: taranis."); System.exit(1); } catch (IOException e) { System.err.println("Couldn't get I/O for " + "the connection to: taranis."); System.exit(1); } BufferedReader stdIn = new BufferedReader(new InputStreamReader(System.in)); String userInput; while ((userInput = stdIn.readLine()) != null) { out.println(userInput); System.out.println("echo: " + in.readLine()); }

Page 16: T5d.tai Lieu Socket Tiengviet

- 15 -

out.close(); in.close(); stdIn.close(); echoSocket.close(); } }

Tiến trình thực hiện bên phía Client như sau

EchoClient tao socket và kết nối đến Server theo địa chỉ và cổng của server

echoSocket = new Socket("localhost", 7); Đọc dữ liệu từ người dùng, sau đó viết vào socket, tiếp theo là đọc dữ liệu

từ socket và viết ra màn hình. while ((userInput = stdIn.readLine()) != null) { out.println(userInput); System.out.println("echo: " + in.readLine()); }

3.2. Ví dụ sử dụng giao thức hướng kết nối TCP: Chúng ta sẽ xây dựng ví dụ về Server thời gian đã được mô tả trong phần 1 của tiểu luận. Chương trình phía server gọi là TimeServer có nhiệm vụ cung cấp thời gian hiện tại của nó cho chương trình client gọi là TimeClientkhi có yêu cầu. Chúng ta sẽ xây dựng hai lớp

TimeServer - Chương trình phía Server TimeClient - Chương trình phía Client

Lớp TimeServer

import java.io.*; import java.net.*; import java.util.*; public class TimeServer { static DatagramSocket socket; public static void main(String[] argv) { try {

Page 17: T5d.tai Lieu Socket Tiengviet

- 16 -

socket = new DatagramSocket(7654); }catch (SocketException e) { System.err.println("Unable to create socket"); e.printStackTrace(); System.exit(1); } DatagramPacket datagram; datagram = new DatagramPacket(new byte[1], 1); while (true) { try { socket.receive(datagram); respond(datagram); }catch (IOException e) { e.printStackTrace(); } } } static void respond(DatagramPacket request) { ByteArrayOutputStream bs; bs = new ByteArrayOutputStream(); DataOutputStream ds = new DataOutputStream(bs); try { ds.writeLong(System.currentTimeMillis()); }catch (IOException e) { } DatagramPacket response; byte[] data = bs.toByteArray(); response = new DatagramPacket(data, data.length, request.getAddress(), request.getPort()); try { socket.send(response); }catch (IOException e) { // Give up, we've done our best.

Page 18: T5d.tai Lieu Socket Tiengviet

- 17 -

} } }

Tiến trình thực hiện ở đây như sau: Tạo socket phía Server để chờ yêu cầu kết nối

socket = new DatagramSocket(7654); Nhận yêu cầu từ phía Client

socket.receive(datagram); Gửi trả yêu cầu về cho Client

response = new DatagramPacket(data, data.length, request.getAddress(), request.getPort()); socket.send(response);

Lớp TimeClient

import java.io.*; import java.net.*; import java.util.*; public class TimeClient { private static boolean usageOk(String[] argv) { argv[] if (argv.length != 1) { String msg = "usage is: " + "TimeClient server-name"; System.out.println(msg); return false; } return true; } public static void main(String[] argv) { if (!usageOk(argv)) System.exit(1); DatagramSocket socket;

Page 19: T5d.tai Lieu Socket Tiengviet

- 18 -

try { socket = new DatagramSocket(); }catch (SocketException e) { System.err.println("Unable to create socket"); e.printStackTrace(); System.exit(1); return; } long time; try { byte[] buf = new byte[1]; socket.send(new DatagramPacket(buf, 1, InetAddress.getByName(argv[0]), 7654)); DatagramPacket response = new DatagramPacket(new byte[8],8); socket.receive(response); ByteArrayInputStream bs; bs = new ByteArrayInputStream(response.getData()); DataInputStream ds = new DataInputStream(bs); time = ds.readLong(); }catch (IOException e) { e.printStackTrace(); System.exit(1); return; } System.out.println(new Date(time)); socket.close(); } }

Tiến trình hoạt động của phía Client như sau: Tạo socket

socket = new DatagramSocket(); Gửi dữ liệu đến Server

Page 20: T5d.tai Lieu Socket Tiengviet

- 19 -

socket.send(new DatagramPacket(buf, 1, InetAddress.getByName(argv[0]), 7654)); Nhận dữ liệu trả lời từ Server

DatagramPacket response = new DatagramPacket(new byte[8],8); socket.receive(response);

Page 21: T5d.tai Lieu Socket Tiengviet

- 20 -

Phần 2. Xây dựng ứng dụng

Chương 1. Phân tích thiết kế

1. Giới thiệu Trong thời đại ngày nay, thông tin liên lạc là một vấn đề vô cùng quan trọng, các hệ thống thông tin ra đời đã đáp ứng được phần nào nhu cầu đó. Đặc biệt là giao tiếp qua mạng máy tính đã trở thành xu thế thời đại bởi không chỉ là nội dung, hình thức, kinh tế mà còn cả bởi tốc độ và tính thuận tiện của nó. Một trong những phương thức trao đổi đang được sử dụng rộng rãi bây giờ chính là CHAT(mà ta tạm dịch la tán gẫu) qua mạng. Trên cơ sở tìm hiểu thực tế, và vì điều kiện thời gian không cho phép chúng tôi có xây dựng một chương trình CHAT cho mạng LAN dựa trên nền tảng lập trình Socket với mô hình Client/Server bằng ngôn ngữ JAVA.

2. Phân tích hệ thống

2.1 Mô hình chung Như đã trình bày trên, yêu cầu của bài toán Chat rất ngắn gọn, ở đây về phía người chat thì chỉ cần tham gia kết nối với máy chủ(đăng nhập) và nếu được phép(đúng Nickname và Password) họ bắt đầu có thể trao đổi thông tin với nhau, thay đổi một số giao diện người dùng và nếu không họ có thể thoát ra khỏi hệ thống. Còn phía nhà quản lý, anh ta cho phép những ai được quyền tham gia mạng Chat và theo dõi chặt chẽ mọi diễn biến của các tiến trình trao đỏi thông tin của các khách hàng, thông báo những diễn biến đột xuất như có thêm một khách hàng đăng nhập hay nột khách hàng rời khỏi hệ thống và ghi lại nhật ký của tiến trình các khách hàng tham gia trên mạng. Như vậy, chương trình được xây dựng cho hai lớp đối tượng cơ bản là phía máy Client và phía máy Server. Mỗi đối tượng sẽ có các chức năng riêng thực hiện các vấn đề của bài toán CHAT qua mạng. Với Server, nó phải quản lý chung các thao tác mà Client đưa tới. Để làm điều này Server phải mở một cổng và sẽ lắng nghe trên đó. Khi nhận được thông tin từ phía Client qua cổng nó sẽ phải kiểm tra đăng nhập và ra các quyết định cần thiết, đồng thời nó cũng luôn theo dõi các tiến trình của máy Client như các quá trình vào ra và ghi lại nhật ký, gửi các message tới các Client khác, đưa các thông tin đăng nhập tới các máy khách,...Phía Client khi tham gia mạng phải kết nối tới Server, nếu thành công thì sẽ bắt đầu tiến trình trao đổi thông điệp do Server quản lý, đồng thời nó có quyền thiết lập một số thuộc tính về giao diện. Khi một Client ngắt kết nối, Server sẽ đưa thông báo tới tất cả các máy Client khác trên mạng mà còn đang kết nối, các máy này sẽ có các thông báo về máy rời khỏi mạng. Như vậy, toàn bộ tiến trình của hệ thống sẽ gồm các công đoạn chính như sau:

Server mở cổng và lắng nghe trên cổng đó

Page 22: T5d.tai Lieu Socket Tiengviet

- 21 -

Client tham gia đăng nhập kết nối với Server trên cổng đã mở thông qua Nickname và Password được cung cấp bởi Server Client bắt đầu quá trình trao đổi thông điệp với nhau bằng cách gửi thông điệp tới Server và Server sẽ gửi thông diệp đó tới Client nhận (nếu gửi theo kiểu cá nhân) hoặc gửi cho tất cả các Client trên mạng(nếu Client đó gửi theo kiểu công cộng). Một Client kết nối thành công sẽ được Server thông báo cho tất cả các Client kết nối trước đó biết và Server sẽ ghi lại các quá trình này trong nhật ký của nó.

Khi một Client không tham gia nữa, Server sẽ đóng kết nối và thông báo tới tất cả các Client còn đang tham gia trên mạng

2.2 Mô hình ca sử dụng Trên cơ sở mô hình như trên, chúng tôi xây dựng mô hình ca sử dụng như sau: Các Actor trong mô hình:

Client Server

Các khung nhìn: Đăng nhập Trao đổi thông điệp Kết thúc(Thoát khỏi hệ thống)

Ta có mô hình ca sử sụng của hệ thống chat như sau:

Hình 1: Mô hình ca sử dụng của hệ thống chat

2.3 Sơ đồ tuần tự Đăng nhập:

D a n g n h a p

T ra o d o i T D

C lie n t

K e t t h u c C h a t

S e rve r

Page 23: T5d.tai Lieu Socket Tiengviet

- 22 -

Client Server

Gui yeu cau ket noi

Kiem tra Nickname & Password

G ui N ick va PassW ord

Cho dang nhap hoac huy bo

Hình 2: Sơ đồ tuần tự của quá trình đăng nhập hệ thống

Trao đổi thông điệp:

Client1 S erver Client2

G ui t hong diep cho Client2 gui cho Client2

Gui cho Client1

Gui cho Client1

Gu i toi t at ca Client Gui cho tat ca Client

Hình 3: Sơ đồ tuần tự của quá trình trao đồi thông điệp

Page 24: T5d.tai Lieu Socket Tiengviet

- 23 -

Thoát kết nối:

Client1 Server Client2

Gui hanh dong thoat

Dap ung, Dong ket noi

Thong bao cho Client2 biet

Hình 4: Sơ đồ tuần tự của quá trình kết thúc ra khỏi hệ thống

2.4 Sơ đồ cộng tác

: Processing

: AdminManager

Mo cong& Lang nghe

: Us erList

: Setting

1: yeu cau ket noi

2: Dap ung yeu cau

Lay thong tin thiet lap

lay thong tin User

Hình5: Sơ đồ cộng tác của hệ thống

Page 25: T5d.tai Lieu Socket Tiengviet

- 24 -

2.5 Biểu đồ lớp

Hình 6: Biểu đồ lớp của hệ thống

C h a t S e rve r

C lie n t S e t t in g

C l ie n t S e t t in g ()

S o c k e t C l ie n t

S oc k e t C li e nt ()m a in ()

S o c k e t S e rve r

m a in ()S o c k e t S e rve r()

B a s e C lie n tB a s e S erv er

C h a t C l ie nt

C h a t M e s s a g e

C h a t M e s s a g e ()

L o g o n F a i le d E x c e p t io n

L o g o n F a il e dE x c e p t io n ()

Page 26: T5d.tai Lieu Socket Tiengviet

- 25 -

Chương 2. Xây dựng chương trình Chương trình dưới đây dược thiết kế trên cơ sỏ lập trình Socket và tham khảo các tài liệu sau:

Lập trình hướng đối tượng với Java - TS. Đoàn Văn Ban – Viện CNTT Kỹ thuật lập trình Java - KS. Đậu Quang Tuấn và Nguyễn Viết Linh Lập trình mạng bằng Java - Trung tâm tin hoc Trí Đức Thinking in Java Java tutorial - Sun

Sau đây ta đi xây dựng chương trình

1. Xây dựng chương trình cho Server ( Lớp SocketServer.java) Server sẽ làm nhiệm vụ lắng nghe các yêu cầu kết nối từ các Client trên một cổng cụ thể thông qua đối tượng ServerSocket, các yêu cầu kết nối được kiểm tra, xếp vào hàng đợi và chờ Server chấp nhận. Ta có sơ đồ thiết kế cơ bản của lớp SocketServer như sau:

Lắng nghe các kếtnối trên cổng 2222

Chấp nhận kết nốivà trả về Sockettương ứng

Khởi tạo Threadphục vụ kết nối

Khởi tạo dòng xuất

Socket và dòng

xuất được quản lý trong bảng băm

Page 27: T5d.tai Lieu Socket Tiengviet

- 26 -

2. Xây dựng chương trình cho Client ( Lớp SocketClient.java) Ta thiết kế một giao diện người sử dụng bao gồm một vùng nhập thông điệp, một vùng hiển thị thông điệp, một vùng hiển thị danh sách các User tham gia mạng, hai nút lệnh gửi thông điệp và nút thoát. Thiết lập một Socket yêu cầu kết nối tới Server với Nickname, tên máy chủ và cổng dịch vụ xác định. Sau khi kết nối được chấp nhận, nó tạo ra hai dòng xuất và nhập tương ứng với socket này. hai dòng xuất và nhập làm nhiệm cụ nhận và gửi thông điệp. Ta có sơ đồ thiết kế cơ bản sau:

Chi tiết về chương trình sẽ được giới thiệu cụ thể riêng với các file kèm theo.

Tạo đối tượng Server yêu cầu kết nối tới máy chủ

Thiết lập dòng xuất nhập tương ứng

Thêm dữ liệu vàovùng nhập

Đọc dữ liệu từ dòng nhập

Lấy chuỗi ký tự từ vùng nhập và gửi tới Server trên dòng xuất

Client

Lắng nghe sự kiện người sử dụng nhấn

chuột