1. Trang chủ
  2. » Luận Văn - Báo Cáo

Viết chương trình trò chuyện đơn giản bằng ngôn ngữ lập trình c

55 20 0

Đang tải... (xem toàn văn)

Tài liệu hạn chế xem trước, để xem đầy đủ mời bạn chọn Tải xuống

THÔNG TIN TÀI LIỆU

Thông tin cơ bản

Định dạng
Số trang 55
Dung lượng 1,56 MB

Các công cụ chuyển đổi và chỉnh sửa cho tài liệu này

Nội dung

Với nhu cầu trao đổi thông tin, liên lạc và trò chuyện trên mạng ngày càng tăng hiện nay, việc nghiên cứu và xây dựng thành công một chương trình Chat sẽ đáp ứng được những nhu cầu cần t

Trang 1

ĐẠI HỌC ĐÀ NẴNG TRƯỜNG ĐẠI HỌC SƯ PHẠM

KHOA TIN HỌC - -

Đề tài:

VIẾT CHƯƠNG TRÌNH TRÒ CHUYỆN ĐƠN GIẢN

BẰNG NGÔN NGỮ LẬP TRÌNH C#

Muc Lục

LỜI MỞ ĐẦU 4

Trang 2

LỜI CẢM ƠN 6

NHẬN XÉT CỦA GIÁO VIÊN HƯỚNG DẪN 7

Chương 1: CƠ SỞ LÝ THUYẾT VÀ ỨNG DỤNG 8

1.1 Sơ lược về lập trình Socket 8

1.1.1 Khái niệm IPAddress và Port 8

1.1.2 Lớp IPAddress 8

1.1.3 Lớp IPEndPoint 9

1.1.4 Lập trình Socket hướng kết nối(TCP) 9

1.1.5 Lập trình Socket phi kết nối(UDP) 10

1.1.6 Lớp Helper của C# Socker 11

1.2 Xử lý tiến trình trong lập trình đa luồng 15

1.2.1 Khái niệm luồng 15

1.2.2 Khảo sát namespace System.Threading 16

1.3 Đồng bộ và bất đồng bộ trong lập trình đa luồng 19

1.4 Hệ mã hóa công khai RSA 22

1.4.1 Khái niệm mã hóa 22

1.4.2 Hệ mã khóa 24

1.4.3 Thuật toán mã hóa RSA 25

Chương 2: PHÂN TÍCH VÀ THIẾT KẾ CHƯƠNG TRÌNH 30

2.1 Phân tích 30

2.1.1 Phân tích nhu cầu thực tiễn 30

2.1.2 Yêu cầu đề ra 30

2.1.3 Phân tích các thành phần xử lý 30

2.1.4 Quá trình xử lý của chương trình 39

2.2 Thiết kế 45

2.2.1 Thiết kế Server 45

2.2.2 Thiết kế Client 48

2.3 Cài đặt và sử dụng chương trình 52

KẾT LUẬN 54

DANH MỤC TÀI LIỆU THAM KHẢO 55

Trang 3

DANH SÁCH HÌNH VẼ SƠ ĐỒ

Hình 1.1 Lập trình socket hướng kết nối (TCP) 6

Hình 1.2 Lập trình socket phi kết nối (UDP) 8

Hình 1.3 Kết quả chương trình đồng bộ hóa 18

Hình 1.4 Kết quả chương trình bất đồng bộ 18

Hình 1.5 Mã hóa 20

Hình 1.6 Mã hóa và giải mã thông tin được truyền đi 20

Hình 1.7 Mã hóa bí mật 21

Hình 1.8 Mã hóa công khai 21

Hình 2.1 Sơ đồ xử lý đăng nhập 28

Hình 2.2 Sơ đồ xử lý đăng xuất 29

Hình 2.3 Sơ đồ xử lý gởi tin nhắn 30

Hình 2.4 Giao diện Server thu gọn 42

Hình 2.5.a Giao diện Server mở rộng chưa kết nối 43

Hình 2.5.b Giao diện Server mở rộng đã có kết nối 43

Hình 2.6 Giao diện Client đăng nhập 44

Hình 2.7 Giao diện Client chính thu gọn 45

Hình 2.8 Giao diện Client Chat room 46

Hình 2.9 Giao din Client tin nhắn riêng tư 47

Hình 2.10 Giao diện Client Chat riêng tư 48

Trang 4

LỜI MỞ ĐẦU

Với sự phát triển của Internet hiện nay, việc viết các phần mềm ứng dụng mạng đã trở nên cần thiết và phổ biến với những nhà phát triển phần mềm Với nhu cầu trao đổi thông tin, liên lạc và trò chuyện trên mạng ngày càng tăng hiện nay, việc nghiên cứu và xây dựng thành công một chương trình Chat sẽ đáp ứng được những nhu cầu cần thiết đó và làm phong phú thêm các phương thức trao đổi

và trò chuyện của các chương trình Chat hiện nay

Với những lý do đặt ra như thế, việc nghiên cứu và xây dựng nên một chương trình Chat phải đảm bảo các tính năng cần thiết và cơ bản nhất như: có thể gởi tin nhắn riêng tư hoặc trong một nhóm giữa các user, tạo ra danh sách bạn bè Việc nghiên cứu và xây dựng một chương trình Chat cần thực hiện một cách kĩ lưỡng và khoa học nhất để có thể tạo ra một ứng dụng có với những tính năng cần thiết, dể dàng sử dụng, tao tác linh hoạt

Để xây dựng thành công một chương trình Chat, em đã tập trung vào những đối tượng và phạm vi nghiên cứu sau:

 Đối tượng nghiên cứu: tìm hiểu cơ chế hoạt động của Socket, các nguyên lý

về lập trình đa luồng, đồng bộ và bất đồng bộ trong lập trình đa luồng, cuối cùng là ứng dụng hệ mã hóa công khai RSA để mã hóa thông tin truyền đi trên mạng

 Phạm vi nghiên cứu: tạo ra một chương trình Chat với tính năng như gởi và nhận tin nhắn dạng text giữa các users với dạng riêng tư hoặc trong một nhóm, mã hóa và giải mã thông tin trước khi truyền đi và sau khi nhận được nhằm đảm bảo tính riêng tư và bảo mật khi truyền dữ liệu Tất cả các quá trình đó được giám sát và điều khiển bởi một Server

Trong báo cáo này em xin trình bày theo kết cấu:

Chương I: CƠ SỞ LÝ THUYẾT VÀ ỨNG DỤNG

Tìm hiểu về lập lập trình Socket bằng ngôn ngữ C#, đưa ra cái nhìn tổng quan

cơ sở lý thuyết chủ đạo trong quá trình xây dựng chương trình Tìm hiểu và ứng dụng hệ mã hóa công khai RSA trong quá trình mã hóa thông tin trước khi truyền

đi

Chương II: PHÂN TÍCH VÀ THIẾT KẾ CHƯƠNG TRÌNH

Trang 5

Đưa ra các bước phân tích từ nghiên cứu thực tế của người sử dụng và vận dụng cơ sở lý thuyết trong việc quá trình xây dựng chương trình Đề ra các giải pháp trong từng bước phân tích nhằm xây dựng chương trình một cách khoa học nhất

Chương III: CÀI ĐẶT VÀ SỬ DỤNG CHƯƠNG TRÌNH

Là cách hướng dẫn người sử dụng phương pháp cài đặt chương trình, yêu cầu hệ thống và các phương pháp sử dụng chương trình

Trang 6

LỜI CẢM ƠN

Bằng sự nổ lực và kiên trì học hỏi trong quá trình thực hiện khóa luận ,

em đã hoàn thành đề tài “ Viết chương trình trò chuyện đơn giản bằng

ngôn ngữ lập trình C#” với sự hướng dẫn của Thầy Ngô Đình Thưởng

Em xin chân thành cảm ơn Thầy Ngô Đình Thưởng đã hướng dẫn em thực hiện khóa luận tốt nghiệp Thầy đã nhiệt tình hướng dẫn và giải đáp mọi thắc mắc trong quá trình thực hiện khóa luận

Em cũng xin chân thành gởi lời cảm ơn đến Thầy Cô trong khoa Tin học, các Anh chị và các bạn đã giúp đỡ trong suốt quá trình thực hiện khóa luận tốt nghiệp Cuối cùng xin chúc quý Thầy cô, các Anh chị cùng các bạn sức khỏe và công tác tốt!

Đà Nẵng, ngày 15 tháng 05 năm 2013

Sinh viên thực hiện

Nguyễn Văn Xuân

Trang 7

NHẬN XÉT CỦA GIÁO VIÊN HƯỚNG DẪN

………

………

………

………

………

………

………

………

………

………

………

………

………

………

Đà Nẵng, ngày tháng năm 2013

Giáo viên hướng dẫn

Ngô Đình Thưởng

Trang 8

Chương 1: CƠ SỞ LÝ THUYẾT VÀ ỨNG DỤNG

1.1 Sơ lược về lập trình Socket

1.1.1 Khái niệm IPAddress và Port

Nguyên lý: Trong một máy có rất nhiều ứng dụng muốn trao đổi với các ứng dụng khác thông qua mạng (VD: Có 2 ứng dụng trên máy A muốn trao đổi với 2 ứng dụng trên máy B) Mỗi máy tính chỉ có duy nhất một đường truyền dữ liệu (để gửi và nhận dữ liệu cho nhau)

Vấn đề: Rất có thể xảy ra "nhầm lẫn" khi dữ liệu từ máy A gửi đến máy B thì không biết là dữ liệu đó gửi cho ứng dụng nào trên máy B? Trong quá trình truyền

và nhận dữ liệu có thể xảy ra lỗi làm mất mát hoặc sai lệch dữ liệu

Giải quyết: Mỗi ứng dụng trên máy B sẽ được gán một số hiệu (gọi là cổng Port), số hiệu cổng này từ 1 65535 Khi ứng dụng trên máy A muốn gửi cho ứng dụng nào trên máy B thì chỉ việc điền thêm số hiệu cổng (vào trường RemotePort) vào gói tin cần gửi Trên máy B, các ứng dụng sẽ việc kiểm tra giá trị cổng trên mỗi gói tin xem có trùng với số hiệu cổng của mình (đã được gán – chính

là giá trị Localport) hay không? Nếu bằng thì xử lý, còn trái lại thì không làm gì Như vậy khi cần trao đổi dữ liệu cho nhau thì hai ứng dụng cần phải biết thông tin tối thiểu là địa chỉ IP (IP Address) và số hiệu cổng (Port) của ứng dụng kia

1.1.2 Lớp IPAddress

IPAddress : là một lớp dùng để mô tả một địa chỉ IP, lớp này có thể sử

dụng trong nhiều phương thức của Socket Một số phương thức của lớp IPAddress

Phương thức:

 Equals: So sánh 2 địa chỉ IP

 GetHashCode: Lấy giá trị hash cho một đối tượng IPAddress

GetType: Trả về kiểu của một thể hiện địa chỉ IP

 HostToNetworkOrder: Chuyển một địa chỉ IP từ host byte order thành network dy order IsLoopBack Cho biết địa chỉ IP có phải là địa chỉ LoopBack hay không

Trang 9

1.1.3 Lớp IPEndPoint

IPEndPoint là một một lớp các đối tượng mô tả sự kết hợp của một địa chỉ IP

và Port Đối tượng trong lớp IPEndPoint được dùng để gắn kết các Socket với các địa chỉ cục bộ hoặc các địa chỉ từ xa

Hai thuộc tính của IPEndPoint có thể được dùng để lấy được vùng các port trên

Trang 10

trình viên nên NET Framework cung cấp một số lớp để giảm gánh nặng lập trình Một trong những lớp đó là NetworkStream, và 2 lớp dùng để gởi và nhận Text

sử dụng giao thức TCP là StreamWriter và StreamReader

Lớp NetworkStream nằm trong namespace System.Net.Sockets, lớp này có nhiều phương thức tạo lập để tạo một thể hiện của lớp NetworkStream nhưng phương thức tạo lập sau hay được dùng nhất:

SocketType.Stream, ProtocolType.TCP);

NetworkStream ns = new NetworkStream(server);

Namespace System.IO chứa 2 lớp StreamReader và StreamWriter điều khiển việc đọc và ghi các thông điệp text từ mạng Cả 2 lớp đều có thể được triển khai với một đối tượng NetworkStream để xác định các hệ thống đánh dấu cho các thông điệp TCP

Lớp StreamReader có nhiều phương thức tạo lập, trong đó phương thức tạo lập đơn giản nhất của lớp StreamReader là :

public StreamReader(Stream stream);

Biến stream có thể được tham chiếu đến bất kì kiểu đối tượng Stream nào kể cả đối tượng NetworkStream Có nhiều phương thức và thuộc tính có thể được dùng với đối tượng StreamReader sau khi nó được tạo ra

Tương tự đối tượng StreamReader, đối tượng StreamWriter có thể được tạo

ra từ một đối tượng NetworkStream:

public StreamWriter(Stream stream);

StreamWriter cũng có nhiều phương thức và thuộc tính kết hợp với nó, một

số phương thức và thuộc tính của lớp StreamReader cũng có trong đối tượng của StreamWrite

1.1.5 Lập trình Socket phi kết nối(UDP)

Các Socket phi kết nối cho phép gởi các thông điệp mà không cần phải thiết lập kết nối trước Một phương thức đọc toàn bộ thông điệp được gởi bởi một phương thức gởi, điều này làm tránh được các rắc rối, phức tạp với biên dữ liệu Thật không may mắn là giao thức phi kết nối UDP không đảm bảo dữ liệu được truyền tới đích Nhiều yếu tố như mạng bận, mạng bị ngắt kết nối giữa chừng có thể ngăn cản các

Trang 11

gói tin được truyền tới đích

Nếu một thiết bị chờ dữ liệu từ một thiết bị ở xa, nó phải được gán một địa chỉ

và port cục bộ, dùng hàm Bin() để gán Một khi đã thực hiện xong, thiết bị có thể dùng Socket để gởi dữ liệu ra ngoài hay nhận dữ liệu từ Socket

Bởi vì thiết bị Client không tạo ra kết nối đến một địa chỉ Server cụ thể do đó phương thức Connect() không cần dùng trong chương trình UDP Client Mô hình bên dưới mô tả các bước lập trình Socket phi kết nối

Hình 1.2 Lập trình socket phi kết nối (UDP)

1.1.6 Lớp Helper của C# Socker

1.1.6.1 Lớp TCPClient:

Lớp TCPClient nằm trong namespace System.Net.Sockets được thiết kế để

hổ trợ cho việc viết ứng dụng của TCP Client được dể dàng Lớp TcpClient cho phép tạo ra một đối tượng Tcp Client, sử dụng một trong ba phương thức tạo lập như sau:

 TcpClient(): Là phương thức tạo lập đầu tiên, đối tượng được tạo ra bởi phương thức tạo lập này sẽ gắn kết với một địa chỉ cục bộ và một Port TCP ngẫu nhiên Sau khi đối tượng TcpClient được tạo ra, nó phải được kết nối đến thiết bị ở xa thông qua phương thức Connect như ví dụ dưới đây:

Trang 12

TcpClient newcon = new TcpClient();

Newcon.Connect(“192.168.1.1”,2011);

 TcpClient(IPEndPoint localEP): Phương thức tạo lập này cho phép chúng ta chỉ ra địa chỉ IP cục bộ cùng với port được dùng Đây là phương thức tạo lập thường được sử dụng khi thiết bị có nhiều hơn một card mạng và chúng ta muốn dữ liệu được gởi trên card mạng nào Phương thức Connect() cũng được dùng để kết nối với thiết bị ở xa:

IPEndPoint iep = new

xa có thể là một chuỗi hostname hoặc một địa chỉ IP Phương thức tạo lập của TcpClient sẽ tự động phân giải hostname thành địa chỉ IP:

TcpClient newcon = new TcpClient(“http://www.cit.udn.vn”,2011);

 Mỗi khi đối tượng TcpClient được tạo ra, nhiều thuộc tính và phương thức có thể được dùng để xử lý việc truyền dữ liệu qua lại giữa các thiết bị Mỗi khi đối tượng TcpClient được tạo ra, nhiều thuộc tính và phương thức

có thể được dùng để xử lý việc truyền dữ liệu qua lại giữa các thiết bị

Phương thức:

 Close(): Đóng kết nối TCP

 Connect(): Thành lập kết nối TCP Client với các thiết bị ở xa

 Equals(): So sánh hai đối tượng TcpClient

 GetHashCode(): Lấy mã hash code

 GetStream(): Lấy đối tượng Stream nó có thể dùng để gởi và nhận dữ liệu

 GetType(): Lấy kiểu của thể hiện hiện tạo

 ToString() Chuyển thể hiện hiện tại sang kiểu chuỗi

Mỗi khi kết nối được thành lập, phương thức GetStream() gán một đối tượng NetworkStream để gởi và nhận vào phương thức Read() và Write() Lớp

Trang 13

TcpClient còn có nhiều thuộc tính được mô tả như sau

 ReceiveBufferSize: Lấy hoặc thiết lập kích thước bộ đệm TCP nhận

 ReceiveTimeout: Lấy hoặc thiết lập thời gian timeout của Socket

 SendBufferSize: Lấy hoặc thiết lập kích thước bộ đệm TCP gởi

 SendTimeout: Lấy hoặc thiết lập giá trị timeout của Socket

đó thì ta dùng một đối tượng IPEndPoint để chỉ ra địa chỉ IP của card mạng cùng với số port dùng để lắng nghe

Trang 14

 Equals(): So sánh hai đối tượng TcpListener

 GetHashCode(): Lấy hash code

 GetType(): Lấy kiểu của thể hiện hiện tại

 Panding(): Kiểm tra xem yêu cầu đang chờ kết nối hay không

 Start(): Bắt đầu lắng nghe kết nối

 Stop(): Ngừng lắng nghe kết nối

 ToString(): Chuyển đối tượng TcpLisener thành chuỗi

Sau khi đối tượng TcpClient được tạo ra, tất cả các truyền thông với thiết

bị ở xa đó được thực hiện với đối tượng TcpClient mới chứ không phải với đối tượng TcpListener có thể chấp nhận kết nối khác Để đóng đối tượng TcpListener ta dùng phương thức Stop()

 UdpClient(int port): Gán đối tượng UdpClient mới tạo vào một port

 UdpClient(IPEndPoint iep): Gán đối tượng UdpClient mới tạo vào một địa chỉ IP cục bộ và một port

 UdpClient(string host, string port): Gán đối tượng UdpClient mới tạo vào một địa chỉ IP và một port bất kỳ và kết hợp nó với một địa IP ở xa Các phương thức tạo lập của lớp UdpClient tương tự như các phương pháp tạo lập của lớp TcpClient, chúng ta có thể cho hệ thống chọn port thích hợp cho ứng dụng hoặc ta có thể chỉ ra port được dùng trong ứng dụng Nếu ứng dụng UDP phải chấp nhận dữ liệu trên một port nào đó, ta phải định nghĩa port đó trong phương thức tạo lập của lớp UdpClient

Phương thức:

 Close(): Đóng Socket ở bên dưới

 Connect(): Cho phép chỉ ra IPEndPoint ở xa để gởi và nhận dữ liệu

 DropMulticastGroup(): Gở bỏ Socket từ một nhóm UDP Multicast

Trang 15

 Equals(): So sánh hai đối tượng UdpClient

 GetHashCode(): Lấy hash code

 GetType(): Lấy kiểu của đối tượng hiện tại

 JoinMulticastGroup(): Thêm Socket vào một nhóm UDP Multicast

 Receive(): Nhận dữ liệu từ Socket

 Send(): Gởi dữ liệu đến thiết bị ở xa từ Socket

 ToString(): Chuyển đối tượng UdpClient thành chuỗi

1.2 Xử lý tiến trình trong lập trình đa luồng

1.2.1 Khái niệm luồng

Một luồng (Thread) là một chuỗi liên tiếp những sự thực thi trong chương trình Trong một chương trình C#, việc thực thi bắt đầu bằng phương thức main() và tiếp tục cho đến khi kết thúc hàm main() Cấu trúc này rất hay cho những chương trình có một chuỗi xác định những nhiệm vụ liên tiếp Nhưng thường thì một chương trình cần làm nhiều công việc hơn vào cùng một lúc Ví

dụ trong Internet Explorer khi ta đang tải một trang web thì ta nhấn nút back hay một link nào đó, để làm việc này Internet Explorer sẽ phải làm ít nhất là 3 việc:

 Lấy dữ liệu được trả về từ Internet cùng với các tập tin đi kèm

 Thể hiện trang Web

 Xem người dùng có nhập để làm thứ gì khác không

Để đơn giản vấn đề này ta giả sử Internet Explorer chỉ làm hai công việc:

 Xem người dùng có nhập để làm thứ gì khác không

 Xem người dùng có nhập gì không

Để thực hành việc này ta sẽ viết một phương thức dùng để lấy và thể hiện trang Web Giả sử rằng việc trình bày trang Web mất nhiều thời gian (do phải thi hành các đoạn javascript hay các hiệu ứng nào đó …) Vì vậy sau một khoảng thời gian ngắn khoảng 1/12 giây, phương thức sẽ kiểm tra xem người dùng có nhập gì không Nếu có thì nó sẽ đuơc xử lí, nếu không thì việc trình bày trang sẽ được tiếp tục Và sau 1/12 giây việc kiểm tra sẽ được lặp lại Tuy

Trang 16

nhiên viết phương thức này thì rất phức tạp do đó ta sẽ dùng kiến trúc event trong Window nghĩa là khi việc nhập xảy ra hệ thống sẽ thông báo cho ứng dụng bằng cách đưa ra một event Ta sẽ cập nhật phương thức để cho phép dùng các event:

 Ta sẽ viết một bộ xử lí event để đáp ứng đối với việc nhập của người dùng

 Ta sẽ viết một phương thức để lấy và trình bày dữ liệu Phương thức này được thực thi khi ta không làm bất cứ điều gì khác

Ta hãy xem cách phương thức lấy và trình bày trang web làm việc: đầu tiên

nó sẽ tự định thời gian Trong khi nó đang chạy, máy tính không thể đáp ứng việc nhập của người dùng Do đó nó phải chú ý đến việc định thời gian để gọi phương thức kiểm tra việc nhập của người dùng, nghĩa là phương thức vừa chạy vừa quan sát thời gian Bên cạnh đó nó còn phải quan tâm đến việc lưu trữ trạng thái trước khi nó gọi phương thức khác để sau khi phương thức khác thực hiện xong nó sẽ trả về đúng chỗ nó đã dừng Vào thời Window 3.1 đây thực sự

là những gì phải làm để xử lí tình huống này Tuy nhiên ở NT3.1 và sau đó là Windows 95 trở đi đã có việc xử lí đa luồng điều này làm việc giải quyết vấn

đề tiện lợi hơn Dưới đây chúng ta sẽ tìm hiểu một vài lớp cơ bản trong ngôn ngữ lập trình C# và vấn đề đồng bộ hóa (Synchronization) trong lập trình đa luồng

1.2.2 Khảo sát namespace System.Threading

Namespace System.Threading cung cấp một số kiểu dữ liệu cho phép bạn thực hiện lập trình đa luồng Ngoài việc cung cấp những kiểu dữ liệu tượng trưng cho một luồng cụ thể nào đó, namespace này còn định nghĩa những lớp

có thể quản lý một collection các luồng (ThreadPool), một lớp Timer đơn giản (không dựa vào GUI) và các lớp cung cấp truy cập được đồng bộ vào dữ liệu được chia sẽ sử dụng

Trang 17

Một số lớp của namespace System.Threading:

Các lớp thành viên Mô tả

Interlocked Lớp này dùng cung cấp truy cập đồng bộ hóa vào dữ

liệu được chia sẽ sử dụng (shared data)

Moniter Lớp này cung cấp việc đồng bộ hóa các đối tượng luồng

sử dụng khóa chốt (lock) và tín hiệu chờ (wait signal)

Mutex Lớp này cung cấp việc đồng bộ hóa sơ đẳng có thể

được dùng đối với inter process synchronization

Thread Lớp này tượng trưng cho một luồng được thi hành trong

lòng Common Language Runtime Sử dụng lớp này bạn

có khả năng bổ sung những luồng khác trong cùng AppDomain

ThreadPool Lớp này quản lý những luồng có liên hệ với nhau trong

cùng một Process nào đó

Timer Cho biết một delegate có thể được triệu gọi vào một lúc

được khai báo nào đó Tác vụ wait được thi hành bởi luồng trong thread pool

WaitHandle Lớp này tượng trưng cho tất cả các đối tượng đồng bộ

hóa (cho phép multiple wait) vào lúc chạy

ThreadStart Lớp này là một delegate chỉ về hàm hành sự nào đó

phải được thi hành đầu tiên khi một luồng bắt đầu

TimerCallBack Delegate đối với Timer

WaitCallBack Lớp này là một delegate định nghĩa hàm hành sự kêu

gọi lại (callback) đối với ThreadPool user work item.Lớp đơn giản nhất trong tất cả các lớp thuộc Namespace System.Threading

là lớp Thread Lớp này tượng trưng cho một vỏ bọc hướng đối tượng bao quanh một lộ trình thi hành trong lòng một AppDomain nào đó Lớp này định nghĩa một số hàm thực thi (cả static lẫn shared) cho phép bạn tạo mới những luồng từ luồng hiện hành, cũng như cho Sleep, Stop hay Kill một luồng nào đó

Trang 18

Các thành phần static của lớp Thread:

Các thành phần Static Mô tả

CurrentThread Thuộc tính read-only này trả về một quy chiếu về

luồng hiện đang chạy

GetData() Đi lấy vị trí từ slot được khai báo trên luồng hiện

hành đối với domain hiện hành trong luồng

SetData() Cho đặt để trị lên slot được khai báo trên luồng hiện

hành đối với domain hiện hành trong luồng

GetDomain()

GetDomainID()

Đi lấy một qui chiếu về AppDomain hiện hành (hoặc mã nhận diện ID của domain này) mà luồng hiện đang chạy trên đó

Sleep() Cho ngưng luồng hiện hành trong một thời gian nhất

định được khai báo

Ngoài ra lớp Thread cũng hổ trợ các thành viên cấp đối tượng

Các lớp thành viên Mô tả

IsAlive Thuộc tính này trả về một trị boolean cho biết liệu xem

luồng đã khởi đông hay chưa

IsBackground Đi lấy hoặc đặt để giá trị cho biết liệu xem luồng là một

luồng nền hay không

mang tính thân thiện đối với luồng

Priority Đi lấy hoặc đặt để ưu tiên của một luồng Có thể được

gán một trị lấy từ enumeration ThreadPriority (chẳng hạn Normal, Lowest, Highest, BelowNormal, AboveNormal).

ThreadState Đi lấy hoặc đặt để tình trạng của luồng Có thế được

gán từ enumeration ThreadState (chẳng hạn Unstarted, Running, WaitSleepJoin, Suspended, SuspendRequested, AbortRequested, Stopped).

Interrup() Cho ngưng chạy luồng hiện hành

Join() Yêu cầu luồng chờ đối với luồng bị ngưng chạy

Resume() Tiếp tục lại đối với một luồng bị ngưng chạy

Trang 19

Start() Cho bắt đầu thi hành luồng được khai báo bởi delegate

ThreadStart

Suspend() Cho ngưng chạy một luồng Nếu luồng đã bị ngưng rồi,

một triệu gọi hàm Suspend() sẽ không có tác dụng.

Abort() Kết thúc một tiểu trình bằng cách nén ngoại lệ

System.Threading.ThreadAbortException trong mã lệnh đang được chạy

Mã lệnh của tiểu trình bị hủy có thể tắt ngoại lệ ThreadAbortException để thực hiện việc dọn dẹp, nhưng bộ thực thi sẽ tự động nén ngoại lệ này lần nữa

để đảm bảo tiểu trình kết thúc, trừ khi ResetAbort được gọi

1.3 Đồng bộ và bất đồng bộ trong lập trình đa luồng

Đôi khi có thể bạn muốn điều khiển việc truy cập vào một nguồn lực, chẳng hạn các thuộc tính hoặc các hàm của một đối tượng, làm thế nào chỉ một mạch trình được phép thay đổi hoặc sử dụng nguồn lực đó mà thôi Việc đồng

bộ hóa được thể hiện thông qua một cái khóa được thiết lập trên đối tượng, ngăn không cho luồng nào đó truy cập khi mạch trình đi trước chưa xong công việc

Trong phần này, ta sẽ là quen với cơ chế đồng bộ hóa mà Common Language Runtime cung cấp: lệnh lock Nhưng trước tiên, ta cần mô phỏng một nguồn lực được chia sẽ sử dụng bằng cách sử dụng một biến số nguyên đơn giản counter

Để bắt đầu, ta khai báo biến thành viên và khởi gán về zero:

int counter = 0;

Bài toán được đặt ra ở đây như sau: Luồng thứ nhất sẽ đọc trị counter (0) rồi gán giá trị này cho biến trung gian (temp) Tiếp đó tăng trị của temp rồi Sleep một khoảng thời gian Luồng thứ nhất xong việc thì gán trị của temp trả

về cho counter và cho hiển thị trị này Trong khi nó làm công việc, thì luồng thứ hai cũng thực hiện một công việc giống như vậy Ta cho việc này lập này khoảng 1000 lần Kết quả mà ta chờ đợi là hai luồng trên đếm lần lượt tăng biến counter lên 1 và in ra kết quả 1,2, 3, 4 … tuy nhiên ta sẽ xét đoạn chương trình dưới đây và thấy rằng kết quả hoàn toàn khác với những gì mà chúng ta mong đợi

Trang 20

private int counter = 0;

static void Main(string[] args)

Console.WriteLine("Start thread {0}", t1.Name);

Thread t2 = new Thread(new ThreadStart(Incrementer)); t2.IsBackground = true;

t2.Name = "Thread Two"; t2.Start();

Console.WriteLine("Start thread {0}", t2.Name);

{ while (counter < 1000)

{

nt temp = counter; temp++;

Thread.Sleep(1); counter = temp;

Console.WriteLine("Thread {0}

Incrementer: {1}", Thread.CurrentThread.Name, counter); }

Trang 21

} catch (ThreadInterruptedException) {

Console.WriteLine("Thread {0} interrupted! Cleaning up ", Thread.CurrentThread.Name); }

finally {

Console.WriteLine("Thread {0} Existing.", Thread.CurrentThread.Name);

} } } }

Kết quả đạt được là :

Hình 1.3 Kết quả chương trình đồng bộ hóa

Do đó ta cần phải đồng bộ hóa việc truy cập đối tượng counter C# cung cấp đối tượng Lock để thưc hiện công việc đồng bộ hóa này Một lock sẽ đánh dấu một critical section trên đoạn mã đồng thời cung cấp việc đồng bộ hóa đối với đối tượng được chỉ định khi lock có hiệu lực Cú pháp sử dụng một Lock yêu cầu khóa chặt một đối tượng rồi thi hành một câu lệnh hoặc một khối lệnh rồi sẽ mở khóa ở cuối câu hoặc khối lệnh đó C# cung cấp hổ trợ trực tiếp khóa chặt thông qua từ chốt lock Ta sẽ tra qua theo một đối tượng qui chiếu

và theo sau từ chốt là một khối lệnh

lock(expression) statement-block

Trong ví dụ trên, để có được kết quả như mong muốn, ta sẽ sửa hàm

Trang 22

Incrementer lại như sau:

try

{

lock (this) {

while (counter < 1000) {

int temp = counter;

Kết quả thu được sẽ là:

Hình 1.4 Kết quả chương trình bất đồng bộ 1.4 Hệ mã hóa công khai RSA

1.4.1 Khái niệm mã hóa

Trong mọi lĩnh vực kinh tế, chính trị, xã hội, quân sự… luôn có nhu cầu trao đổi thông tin giữa các cá nhân, các công ty, tổ chức, hoặc giữa các quốc gia với nhau Ngày nay, với sự phát triển của công nghệ thông tin đặt biệt là mạng internet thì việc truyền tải thông tin đã dể dàng và nhanh chóng hơn

Trang 23

Hình 1.5 Mã hóa

Và vấn đề đặt ra là tính bảo mật trong quá trình truyền tải thông tin, đặt biệt quan trọng đối với những thông tin liên quan đến chính trị, quân sự, hợp đồng kinh tế… Vì vậy nghành khoa học nghiên cứu vế mã hóa thông tin được phát triển Việc mã hóa là làm cho thông tin biến sang một dạng khác khi đó chỉ

có bên gửi và bên nhận mới đọc được, còn người ngoài dù nhận được thông tin nhưng cũng không thể hiểu được nôi dung

Hình 1.6 Mã hóa và giải mã thông tin được truyền đi

Như chúng ta thấy ở mô hình 1.5 : Việc trao đổi thông tin được thực hiện qua các bước sau:

 Tạo ra thông tin cần gởi đi

 Gởi thông tin này cho đối tác

Ở mô hình 1.6: Việc trao đổi thông tin được thực hiện:

 Tạo thông tin cần gởi

 Mã hóa và gởi thông tin đã được mã hóa đi

 Đối tác nhận và giải mã thông tin

 Đối tác có được thông tin ban đầu của người gởi

Với 2 thao tác mã hóa và giải mã ta đã đảm bảo thông tin được gửi an toàn

và chính xác

Chúng ta có nhiều phương pháp để mã hóa thông tin: Ở đây ta tìm hiểu về

hệ mã hóa công khai RSA

Trang 24

1.4.2 Hệ mã khóa

Mã khóa bí mật: thông tin sẻ được mã hóa theo một phương pháp ứng với một key, key này dùng để lập mã và đồng thời cũng để giải mã Vì vậy key phải được giữ bí mật, chỉ có người lập mã và người nhận biết được, nếu key

bị lộ thì người ngoài sẽ dể dàng giải mã và đọc được thông tin

Hình 1.7 Mã hóa bí mật

Mã khóa công khai: sử dụng 2 key public key- private key

Public key: Được sử dụng để mã hoá những thông tin mà ta muốn chia sẻ với bất cứ ai Chính vì vậy ta có thể tự do phân phát nó cho bất cứ ai mà ta cần chia sẻ thông tin ở dạng mã hoá

Private key: Đúng như cái tên, Key này thuộc sở hữu riêng tư của bạn(ứng với public key) và nó được sử dụng để giải mã thông tin Chỉ mình bạn sở hữu

nó, Key này không được phép và không nên phân phát cho bất cứ ai

Nghĩa là mỗi người sẽ giữ 2 key 1 dùng để mã hóa key này được công bố rộng rãi, 1 dùng để giải mã key này giữ kín

Khi ai đó có nhu cầu trao đổi thông tin với bạn, sẽ dùng public key mà bạn công bố để mã hóa thông tin và gửi cho bạn, khi nhận được bạn dùng private key để giải mã Những người khác dù có nhận được thông tin nhưng không biết được private key thì cũng không thể giải mã và đọc được thông tin

Hình 1.8 Mã hóa công khai

Trang 25

1.4.3 Thuật toán mã hóa RSA

Thuật toán RSA có hai khóa: Khóa công khai (hay khóa công cộng) và khóa bí mật (hay khóa cá nhân) Mỗi khóa là những số cố định sử dụng trong quá trình mã hóa và giải mã Khóa công khai được công bố rộng rãi cho mọi người và được dùng để mã hóa Những thông tin được mã hóa bằng khóa công khai chỉ có thể được giải mã bằng khóa bí mật tương ứng Nói cách khác, mọi người đều có thể mã hóa nhưng chỉ có người biết khóa cá nhân (bí mật) mới có thể giải mã được

Ta có thể mô phỏng trực quan một hệ mật mã khoá công khai như sau :

B muốn gửi cho A một thông tin mật mà B muốn duy nhất A có thể đọc được

Để làm được điều này, A gửi cho B một chiếc hộp có khóa đã mở sẵn và giữ lại chìa khóa B nhận chiếc hộp, cho vào đó một tờ giấy viết thư bình thường

và khóa lại (như loại khoá thông thường chỉ cần sập chốt lại, sau khi sập chốt khóa ngay cả B cũng không thể mở lại được-không đọc lại hay sửa thông tin trong thư được nữa) Sau đó B gửi chiếc hộp lại cho A A mở hộp với chìa khóa của mình và đọc thông tin trong thư Trong ví dụ này, chiếc hộp với khóa mở đóng vai trò khóa công khai, chiếc chìa khóa chính là khóa bí mật

Tạo khóa:

Giả sử A và B cần trao đổi thông tin bí mật thông qua một kênh không an toàn (ví dụ như Internet) Với thuật toán RSA, A đầu tiên cần tạo ra cho mình cặp khóa gồm khóa công khai và khóa bí mật theo các bước sau:

a) Chọn 2 số nguyên tố lớn p và q với p≠q , lựa chọn ngẫu nhiên và độc

lập

b) Tính: n=pq

c) Tính: giá trị hàm số: (n)=(p-1)(q-1)

d) Chọn một số tự nhiên e sao cho 1<e<(n) và là số nguyên tố cùng nhau

với (n) Công bố (n,e).

e) Tính: d sao cho de1(mod (n))

Một số lưu ý:

 Các số nguyên tố thường được chọn bằng phương pháp thử xác suất

 Các bước 4 và 5 có thể được thực hiện bằng giải thuật Euclide mở rộng

Trang 26

 Bước 5 có thể viết cách khác: Tìm số tự nhiên x sao cho

Khi đó sử dụng giá trị d=mod(p-1)(q-1)

 Từ bước 3 sử dụng =LCM(p-1,q-1) thay cho (n)=(p-1)(q-1)

Khóa công khai bao gồm:

Một dạng khác của khóa bí mật bao gồm:

p and q, hai số nguyên tố chọn ban đầu,

d mod (p-1) và d mod (q-1) (thường được gọi là dmp1 và dmq1),

(1/q) mod p (thường được gọi là iqmp)

Dạng này cho phép thực hiện giải mã và ký nhanh hơn với việc sử dụng định

lý số dư Trung Quốc (tiếng Anh: Chinese Remainder Theorem - CRT) Ở dạng

này, tất cả thành phần của khóa bí mật phải được giữ bí mật

A gửi khóa công khai cho B, và giữ bí mật khóa cá nhân của mình Ở đây, p

và q giữ vai trò rất quan trọng Chúng là các phân tố của n và cho phép tính d khi biết e Nếu không sử dụng dạng sau của khóa bí mật (dạng CRT) thì p và q sẽ

được xóa ngay sau khi thực hiện xong quá trình tạo khóa

Mã hóa

Giả sử B muốn gửi đoạn thông tin M cho A Đầu tiên B chuyển M thành một

số m < n theo một hàm có thể đảo ngược (từ m có thể xác định lại M) được thỏa

thuận trước Quá trình này được mô tả ở phần sau “Chuyển đổi văn bản rõ”

Lúc này B có m và biết n cũng như e do A gửi B sẽ tính c là bản mã hóa của

m theo công thức:

c≡m e mod n

Hàm trên có thể tính dễ dàng sử dụng phương pháp tính hàm mũ (theo

môđun) bằng (thuật toán bình phương và nhân) Cuối cùng B gửi c cho A

Trang 27

p = 61 (số nguyên tố thứ nhất (giữ bí mật hoặc hủy sau khi tạo khóa))

q = 53 ( số nguyên tố thứ hai (giữ bí mật hoặc hủy sau khi tạo khóa))

n = pq = 3233 (môđun (công bố công khai))

e = 17 (số mũ công khai)

d = 2753 ( số mũ bí mật)

Khóa công khai là cặp (e, n) Khóa bí mật là d Hàm mã hóa là:

encrypt(m) = m e mod n = m 17 mod 3233

với m là văn bản rõ Hàm giải mã là:

decrypt(c) = c d mod n = c2753 mod 3233

Ngày đăng: 26/06/2021, 13:17

Nguồn tham khảo

Tài liệu tham khảo Loại Chi tiết
1. Giáo trình “Mạng Máy Tính” , khoa Tin Học ĐH Sư Phạm Sách, tạp chí
Tiêu đề: Mạng Máy Tính
2. Giáo trình “Lập Trình Chuyên Nâng Cao”, Tác Giả: Trần Uyên Trang Sách, tạp chí
Tiêu đề: Lập Trình Chuyên Nâng Cao
3. Giáo trình “Truyền Và Bảo Mật Thông Tin”, Lê Thị Bích Hồng Sách, tạp chí
Tiêu đề: Truyền Và Bảo Mật Thông Tin
4. Dương Quang Thiện, 2005, .NET toàn tập Khác
5. Nguyễn Ngọc Bình Phương, 2005, Các giải pháp lập trình C# Khác
6. Mai Lam, 2010, Giáo trình lập trình ứng dụng mạng. Website Khác

HÌNH ẢNH LIÊN QUAN

Hình 1.1 Lập trình socket hướng kết nối(TCP) - Viết chương trình trò chuyện đơn giản bằng ngôn ngữ lập trình c
Hình 1.1 Lập trình socket hướng kết nối(TCP) (Trang 9)
Hình 1.2 Lập trình socket phi kết nối(UDP) - Viết chương trình trò chuyện đơn giản bằng ngôn ngữ lập trình c
Hình 1.2 Lập trình socket phi kết nối(UDP) (Trang 11)
Hình 1.4 Kết quả chương trình bất đồng bộ 1.4. Hệ mã hóa công khai RSA  - Viết chương trình trò chuyện đơn giản bằng ngôn ngữ lập trình c
Hình 1.4 Kết quả chương trình bất đồng bộ 1.4. Hệ mã hóa công khai RSA (Trang 22)
Hình 1.6 Mã hóa và giải mã thông tin được truyền đi. - Viết chương trình trò chuyện đơn giản bằng ngôn ngữ lập trình c
Hình 1.6 Mã hóa và giải mã thông tin được truyền đi (Trang 23)
Hình 1.5 Mã hóa - Viết chương trình trò chuyện đơn giản bằng ngôn ngữ lập trình c
Hình 1.5 Mã hóa (Trang 23)
Hình 1.8 Mã hóa công khai - Viết chương trình trò chuyện đơn giản bằng ngôn ngữ lập trình c
Hình 1.8 Mã hóa công khai (Trang 24)
 Mô hình xử lý: - Viết chương trình trò chuyện đơn giản bằng ngôn ngữ lập trình c
h ình xử lý: (Trang 31)
 Mô hình xử lý: - Viết chương trình trò chuyện đơn giản bằng ngôn ngữ lập trình c
h ình xử lý: (Trang 33)
 Mô hình xử lý: - Viết chương trình trò chuyện đơn giản bằng ngôn ngữ lập trình c
h ình xử lý: (Trang 34)
Cũng như tương tự các chương trình hoạt động theo mô hình Client – Server,  chương  trình  hoạt   động  chủ  yếu  dựa  vào  gởi  và  nhận  các  request - Viết chương trình trò chuyện đơn giản bằng ngôn ngữ lập trình c
ng như tương tự các chương trình hoạt động theo mô hình Client – Server, chương trình hoạt động chủ yếu dựa vào gởi và nhận các request (Trang 39)
2.1.4. Quá trình xử lý của chƣơng trình - Viết chương trình trò chuyện đơn giản bằng ngôn ngữ lập trình c
2.1.4. Quá trình xử lý của chƣơng trình (Trang 39)
 Giao diện thu gọn hình 2.4: - Viết chương trình trò chuyện đơn giản bằng ngôn ngữ lập trình c
iao diện thu gọn hình 2.4: (Trang 45)
Hình 2.4 Giao diện Server thu gọn - Viết chương trình trò chuyện đơn giản bằng ngôn ngữ lập trình c
Hình 2.4 Giao diện Server thu gọn (Trang 46)
Hình 2.5.b: Giao diện Server mở rộng đã có kết nối. - Viết chương trình trò chuyện đơn giản bằng ngôn ngữ lập trình c
Hình 2.5.b Giao diện Server mở rộng đã có kết nối (Trang 47)
Hình 2.5.a: Giao diện Server mở rộng chưa kết nối. - Viết chương trình trò chuyện đơn giản bằng ngôn ngữ lập trình c
Hình 2.5.a Giao diện Server mở rộng chưa kết nối (Trang 47)
 Giao diện đăng nhập hình 2.6: - Viết chương trình trò chuyện đơn giản bằng ngôn ngữ lập trình c
iao diện đăng nhập hình 2.6: (Trang 48)
 Sau khi đăng nhập sẽ trở về giao diện chính hình 2.7: - Viết chương trình trò chuyện đơn giản bằng ngôn ngữ lập trình c
au khi đăng nhập sẽ trở về giao diện chính hình 2.7: (Trang 49)
Hình 2.8 Giao diện Client Chat room - Viết chương trình trò chuyện đơn giản bằng ngôn ngữ lập trình c
Hình 2.8 Giao diện Client Chat room (Trang 50)
Hình 2.9 Giao diện Client tin nhắn riêng tư. - Viết chương trình trò chuyện đơn giản bằng ngôn ngữ lập trình c
Hình 2.9 Giao diện Client tin nhắn riêng tư (Trang 51)
Hình 2.10: Giao diện Client Chat riêng tư. - Viết chương trình trò chuyện đơn giản bằng ngôn ngữ lập trình c
Hình 2.10 Giao diện Client Chat riêng tư (Trang 52)

TỪ KHÓA LIÊN QUAN

TÀI LIỆU CÙNG NGƯỜI DÙNG

TÀI LIỆU LIÊN QUAN

🧩 Sản phẩm bạn có thể quan tâm

w