Khái niệm các loại máy chủ
 Máy chủ xứ lý đồng thời, đa tiến trình, hướng kết nối
 Ví dụ về Máy chủ xử lý đồng thời, đa tiến trình, hướng 
kết nối
 Máy chủ xử lý đồng thời, đơn tiến trình, hướng kết nối
 Ví dụ về Máy chủ xử lý đồng thời, đơn tiến trình, hướng 
kết nối
              
                                            
                                
            
 
            
                 57 trang
57 trang | 
Chia sẻ: Mr Hưng | Lượt xem: 994 | Lượt tải: 0 
              
            Bạn đang xem trước 20 trang nội dung tài liệu Lập trình máy chủ, để xem tài liệu hoàn chỉnh bạn click vào nút DOWNLOAD ở trên
1Network programming
Lập trình máy chủ
Giáo viên: Nguyễn Hoài Sơn
Bộ môn Mạng và Truyền thông máy tính
Trường Đại học Công nghệ
2Network programming
Nội dung bài học
 Khái niệm các loại máy chủ
 Máy chủ xứ lý đồng thời, đa tiến trình, hướng kết nối
 Ví dụ về Máy chủ xử lý đồng thời, đa tiến trình, hướng 
kết nối
 Máy chủ xử lý đồng thời, đơn tiến trình, hướng kết nối
 Ví dụ về Máy chủ xử lý đồng thời, đơn tiến trình, hướng 
kết nối
3Network programming
Đặt vấn đề 
 Yêu cầu với máy chủ: 
 Đảm bảo chất lượng dịch vụ
 Đáp ứng đồng thời các yêu cầu của nhiều máy khách 
cùng một lúc
 Thời gian đáp ứng yêu cầu của máy khách là nhỏ
 Chi phí thấp
 Dung lượng bộ nhớ sử dụng, tài nguyên tính toán
 Dễ thiết kế, xây dựng và bảo trì
4Network programming
Phân loại máy chủ theo cách thức 
cung cấp dịch vụ
Không kết nối
Hướng kết nối
Tuần tự Đồng thời
Tuần tự không 
kết nối
Đồng thời 
không kết nối
Tuần tự hướng 
kết nối
Đồng thời 
hướng kết nối
5Network programming
Máy chủ không kết nối
 Máy chủ sử dụng giao thức UDP
 Không có kết nối giữa máy khách và máy chủ
 Ưu điểm
 Chỉ cần một socket
 Thích hợp với kiểu truyền tin quảng bá/quảng phát
 Người lập trình được tự do lựa chọn cách thức thực thi tính 
tin cậy trong truyền tin
 Nhược điểm
 Cung cấp tính tin cậy đòi hỏi chi phí cao với người lập trình
6Network programming
Máy chủ hướng kết nối
 Máy chủ sử dụng giao thức TCP
 Sử dụng khái niệm kết nối trong truyền tin
 Chấp nhận kết nối từ máy khách
 Tất cả các thông tin được gửi qua kết nối giữa máy chủ và
máy khách
 Đóng kết nối sau khi kết thúc truyền tin
 Ưu điểm
 Truyền tin tin cậy
 Nhược điểm
 Chi phí cao: phải tạo socket riêng cho từng kết nối với máy 
khách
7Network programming
Khái niệm xử lý tuần tự/xử lý đồng 
thời 
 Chương trình xử lý tuần tự
 Một tiến trình/một luồng điều khiển việc xuất nhập 
dữ liệu
 Xử lý tuần tự từng yêu cầu của mỗi máy khách
 Dễ thực hiện
 Chương trình xử lý đồng thời
 Nhiều tiến trình/luồng điều khiển việc xuất nhập 
và xử lý dữ liệu
 Các tiến trình/luồng thực hiện đồng thời
 Khó thực hiện
8Network programming
Máy chủ xử lý tuần tự
 Tại mỗi thời điểm, xử lý một yêu cầu
 Đưa các yêu cầu mới vào một hàng đợi
 Yêu cầu của một máy khách chỉ được xử lý khi yêu cầu trước đó
được xử lý xong
 Dễ thực thi nhưng kém hiệu quả
 Nhất là trường hợp yêu cầu xử lý ít phải chờ yêu cầu xử lý 
nhiều kết thúc
Server
Client1
Client2
Receiving requests from Client 1
Receiving requests from Client 2
9Network programming
Cách thực hiện máy chủ xử lý tuần tự
 Một máy chủ xử lý tuần tự thực hiện theo các bước 
đơn giản sau
 Tạo socket và gán thông tin cổng cho socket
 Lặp lại
 Chấp nhận yêu cầu từ máy khách
 Xử lý yêu cầu
 Tạo thông báo kết quả và gửi trả lại máy khách
 Trong trường hợp của máy chủ xử lý tuần tự 
hướng kết nối
 Tại mỗi thời điểm, máy chủ xử lý từng yêu cầu đến từ một 
kết nối tới một máy khách
10Network programming
TCP client
TCP server
socket()
socket()
bind()
listen()
accept()
read()
write()
close()
read()
connect()
write()
close()
Connection
request
EOF
Wait next
request
Process request
read()
data (request)
data (reply) 
Send 
next request
11Network programming
Máy chủ xử lý đồng thời
 Có thể xử lý nhiều yêu cầu đến cùng một lúc
 Máy khách không cần đợi yêu cầu trước đó kết thúc
 Hiệu quả cao hơn máy chủ xử lý tuần tự trong hầu 
hết các trường hợp nhưng khó thực hiện hơn
Server
Client1
Client2
Receiving requests from Client 1
Receiving requests from Client 2
12Network programming
Cách thực thi máy chủ xử lý đồng 
thời
 Đa tiến trình
 Tạo ra nhiều tiến trình
 Mỗi tiến trình xử lý một yêu cầu của máy khách
 Đa luồng
 Tạo ra nhiều luồng
 Mỗi luồng xử lý một yêu cầu của máy khách
 Đa xuất nhập (I/O multiplex)
 Đơn tiến trình
 Xuất nhập dữ liệu tại nhiều socket cùng một lúc
 Nhận dữ liệu đồng thời từ nhiều kết nối, xử lý tuần tự các 
yêu cầu
13Network programming
Xử lý đồng thời tốt trong trường hợp 
nào?
 Trả lời một yêu cầu cần nhiều thời gian 
xuất/nhập dữ liệu
 E.g. File transfer, Telnet, Web server,
 Thời gian xử lý các yêu cầu của máy khách là
khác nhau lớn
 Máy chủ chạy trên một máy tính có nhiều bộ 
vi xử lý
14Network programming
Máy chủ xử lý đồng thời, 
không kết nối, đa tiến trình
15Network programming
Máy chủ xử lý đồng thời, không kết nối, đa 
tiến trình
 Bước 1 tiến trình mẹ: Khởi tạo socket, gán 
thông tin cho socket
 Bước 2 tiến trình mẹ: Lặp lại lệnh recvfrom( ) 
để nhận yêu cầu từ máy khách và khởi tạo 
tiến trình con để xử lý yêu cầu của máy 
khách
16Network programming
Máy chủ xử lý đồng thời, không kết nối (2)
 Bước 1 tiến trình con: Xử lý yêu cầu của máy khách
 Bước 2 tiến trình con: Tạo thông báo trả lời và gửi 
trả lại máy khách bởi hàm sendto( )
 Bước 3 tiến trình con: Kết thúc sau khi xử lý xong 
yêu cầu
 Do chi phí cao khi khởi tạo một tiến trình con nên ít 
máy chủ không kết nối sử dụng cách xử lý đồng thời 
đa tiến trình
17Network programming
Máy chủ xử lý đồng thời, 
hướng kết nối, đa tiến trình
18Network programming
Thực thi máy chủ xử lý đồng thời, hướng kết 
nối đa tiến trình như thế nào?
 Lệnh accept dừng thực thi của máy chủ để 
đợi kết nối đến cổng chờ
 Khi có kết nối từ máy khách, tiến trình mẹ 
sẽ khởi tạo một tiến trình con để xử lý kết 
nối
 Tiến trình mẹ sẽ chờ để chấp nhận một kết 
nối khác
19Network programming
Socket for socket for individual
connection connections
requests
master
slave1 slave2 slaven
Server 
application 
processes
Operating 
system
20Network programming
Cách thực thi máy chủ xử lý đồng 
thời, hướng kết nối, đa tiến trình
 Bước 1 tiến trình mẹ: Khởi tạo socket, gán 
thông tin cho socket và chuyển socket sang 
trạng thái thụ động, chờ kết nối
 Bước 2 tiến trình mẹ: Lặp lại:
 Gọi accept() chờ kết nối máy khách
 Khi có kết nối từ máy khách, khởi tạo một tiến trình 
con để xử lý dữ liệu qua kết nối với máy khách
21Network programming
Cách thực thi máy chủ xử lý đồng 
thời, hướng kết nối, đa tiến trình (2)
 Bước 1 tiến trình con: Nhận socket kết nối với 
máy khách
 Bước 2 tiến trình con: Đọc yêu cầu của máy 
khách, xử lý yêu cầu và gửi thông báo trả lời cho 
máy khách
 Bước 3 tiến trình con: Đóng kết nối và thoát sau 
khi xử lý xong yêu cầu của máy khách
22Network programming
fork(): Tạo tiến trình mới
 Khởi tạo một tiến trình con chỉ khác tiến trình mẹ ở 
PID và PPID
 Gọi một lần nhưng trả về 2 lần
 Trả về trên tiến trình mẹ với giá trị trả về là PID của tiến 
trình con
 Trả về trên tiến trình con, với giá trị trả về là 0
 Lấy PID của tiến trình mẹ bằng hàm getppid()
#include 
pid_t fork(void);
Returns: 0 in child, process ID of child in parent, -1 on error
23Network programming
2 cách sử dụng điển hình với fork
 Một tiến trình muốn thực hiện nhiều công việc 
cùng một lúc
 Tiến trình sẽ tạo ra một bản copy của nó. Mỗi bản 
copy sẽ thực hiện một công việc
 Một tiến trình muốn chạy một chương trình 
khác
 Tiến trình sẽ tạo ra một bản copy của nó và bản 
copy đó sẽ chạy chương trình mới
24Network programming
Ví dụ về máy chủ ECHO xử lý đồng thời, đa 
tiến trình
 tcpserv02.c
25Network programming
Chi tiết về xử lý đồng bộ
 Tiến trình mẹ
 đóng socket kết nối connfd của kết nối mới
 sử dụng socket chờ listenfd để tiếp tục chờ kết nối mới 
 Tiến trình con
 đóng socket chờ istenfd
 cung cấp dịch vụ echo (str_echo(connfd)) thông qua kết nối mới
 tiết tục sử dụng socket kết nối connfd cho đến khi thoát 
ra (exit)
 Tiến trình con phải thoát ra (exit) sau khi đã thực hiện xong dịch 
vụ
 Lệnh Exit được sử dụng để kết thúc tiến trình
 Khi tiến trình con kết thúc, hệ thống sẽ tự động đóng các socket kết nối 
lại
26Network programming
Xử lý đồng bộ với fork()
connect()
listenfd
client server
connection request
connection
connfd
Server(parent)
listenfd
connfd
Server (child)
fork()
connection
(child)
27Network programming
Vấn đề tiến trình không kết thúc hoàn toàn
 Một tín hiệu (SIGCHLD) sẽ được gửi đến tiến trình 
mẹ khi một tiến trình con kết thúc
 Tiến trình con sau khi kết thúc sẽ tồn tại ở trạng 
thái zombie cho đến khi tiến trình mẹ thực hiện 
lệnh gọi wait3 (wait, waitpid)
 linux % ps -o pid,ppid,tty,stat,args,wchan
PID PPID TT STAT COMMAND WCHAN 
3674 3453 pts/3 S+ ./daytime_server -
3676 3674 pts/3 Z+ [daytime_server] exit
 Tiến trình zombie sẽ làm tốn tài nguyên máy tính
 chiếm chỗ trên bộ nhớ
28Network programming
Giải quyết vấn đề tiến trình không kết 
thúc hoàn toàn như thế nào?
 Tiến trình mẹ sẽ bắt tín hiệu kết thúc của tiến 
trình con và gọi hàm xử lý tín hiệu 
signal(SIGCHLD, sig_chld)
 Hàm signal biểu thị rằng tiến trình mẹ cần gọi 
hàm sig_chld mỗi khi nó nhận được tín hiệu 
SIGCHLD báo hiệu một tiến trình con đã kết 
thúc
 Hàm sig_chld gọi hàm wait3 để hoàn thành việc 
kết thúc của tiến trình con
29Network programming
/* sig_chld - clean up zombie child */
void sig_chld(int signo){
int status;
while (wait3(&status, WNOHANG, (struct rusage 
*) 0) >= 0)
/* empty */;
}
 Giá trị status sau khi hàm wait3 trả về sẽ cho biết 
trạng thái kết thúc của tiến trình con
 Tùy chọn WNOHANG cho phép tiến trình mẹ 
không bị dừng thực thi nếu không có tiến trình 
con nào kết thúc
30Network programming
Cách viết khác của hàm sig_chld
/* reaper - clean up zombie child */
void sig_chld (int sig)
{
pid_t pid;
int status
while ((pid = waitpid (-1, &status, WNOHANG) )> 0)
/* empty */;
return;
}
 waitpid trả về giá trị là cấu trúc status để có thể kiểm tra thông tin về tiến 
trình con đã kết thúc
 Tùy chọn –1 để chỉ đợi tiến trình con thứ nhất
31Network programming
Xử lý cuộc gọi hệ thống bị ngắt như 
thế nào?
 Vấn đề:
 Tín hiệu SIGCHLD được tạo ra khi tiến trình 
mẹ đang ngừng thực thi để chờ chấp nhận kết 
nối mới. Điều gì xảy ra khi hàm xử lý tín hiệu 
trả về giá trị?
 Hàm accept sẽ trả về giá trị lỗi là EINTR 
(interrupted signal call). Tiến trình mẹ cần phải 
bỏ qua lỗi này.
If ((ssock=accept(.)) <0)
if (errno = EINTR) continue;
else err_sys(“accept error”);
32Network programming
Ví dụ về máy chủ ECHO xử lý đồng thời, đa 
tiến trình
 tcpserv03.c
33Network programming
Máy chủ hướng kết nối, xử 
lý đồng thời, đơn tiến trình
34Network programming
Tại sao lại xử lý đồng thời đơn tiến trình?
 Chi phí khi tạo tiến trình
 Chia sẻ thông tin giữa các kết nối được dễ dàng
 Máy chủ xử lý đồng thời sẽ xử lý một cách tuần tự 
nếu thời gian xử lý một yêu cầu của máy khách là
ngắn
 Sử dụng đa tiến trình chỉ có hiệu quả khi CPU không thể 
xử lý các yêu cấu một cách tuần tự
request1 request 2 request 3
CPU time
request1 request 2 request 1
CPU time
request 3 request 1
35Network programming
Thực hiện xử lý đồng thời đơn tiến trình 
như thế nào?
 Một máy chủ đồng thời, đơn tiến trình sẽ phải 
thực hiện chức năng của cả tiến trình mẹ và
tiến trình con trong mô hình máy chủ đa tiến 
trình
 Duy trì một tập các sockets
 Một socket sẽ được gán với cổng lắng nghe để chấp 
nhận kết nối mới đến
 Các socket khác sẽ ứng với các kết nối đến các máy 
khách
36Network programming
server Server 
<---
application 
process
Operating 
<--- system
Socket lắng 
nghe yêu cầu 
kết nối
Socket kết nối ứng với 
mỗi kết nối riêng biệt
37Network programming
Thực hiện xử lý đồng thời đơn tiến trình 
như thế nào? (2)
 Nếu socket lắng nghe sẵn sàng, tiến trình sẽ gọi 
hàm accept() để chấp nhận kết nối mới đến
 Nếu socket kết nối sẵn sàng, tiến trình sẽ gọi hàm 
read() để nhận yêu cầu đến từ máy khách, xử lý yêu 
cầu và gửi trả lại kết quả xử lý
 Sau đó các bước trên được lặp lại
 Làm thế nào để đợi xuất nhập dữ liệu trên tất cả các 
sockets và biết socket nào đã sẵn sàng?
38Network programming
Các mô hình xuất nhập dữ liệu
 Xuất nhập chặn (Blocking I/O)
 Xuất nhập không chặn (Nonblocking I/O)
 Đa xuất nhập (I/O multiplexing)
 Xuất nhập dựa tín hiệu (signal driven I/O) 
(SIGIO)
 Xuất nhập không đồng bộ (asynchronous I/O)
39Network programming
Blocking I/O Model
recvfrom
application kernel
system call no datagram ready
datagram ready
copy datagram
copy complete
wait for
data
copy data
from kernel
to user
process 
datagram
process
blocks in
call to
recvfrom
return OK
40Network programming
Nonblocking model
recvfrom
application kernel
system call
no datagram ready
datagram ready
copy datagram
copy complete
wait for
data
copy data
from kernel
to user
process 
datagram
process
repeatedly 
call recvfrom,
waiting for 
an OK return
return OK
EWOULDBLOCK
recvfrom
system call
no datagram ready
EWOULDBLOCK
recvfrom system call
41Network programming
I/O Multiplexing Model 
recvfrom
application kernel
system call
no datagram ready
datagram ready
copy datagram
copy complete
wait for
data
copy data
from kernel
to user
process 
datagram
process blocks 
in call to 
select, waiting
for one of 
possibly many 
sockets to 
become readable
return OK
select
return readable
system call
process blocks 
while data is 
copied into 
application
buffer
42Network programming
Signal-driven I/O model
recvfrom
application kernel
sigaction system call
datagram ready
copy datagram
copy complete
wait 
for
data
copy 
data
from 
kernel
to userprocess 
datagram
process 
continues
executing
return OK
establish
SIGIO signal
handler
deliver SIGIO
system call
process blocks 
while data is 
copied into 
application
buffer
return
signal 
handler
43Network programming
Asynchronous I/O Model 
aio_read
application kernel
system call no datagram ready
datagram ready
copy datagram
copy complete
wait for
data
copy data
from kernel
to user
signal 
handler
process 
datagram
process
continues
executing
deliver signal
return
specified in 
aio_read
44Network programming
Hàm gọi select
 Hàm Select cung cấp xuất nhật dữ liệu không đồng 
bộ bằng cách cho phép một tiến trình có thể đợi trạng 
thái sẵn sàng đầu tiên của nhiều sockets trong một 
tập mô tả file đã được định sẵn 
 Không chỉ có socket
 Có thể thiết lập thời gian timeout tối đa
 Ví dụ, hàm select sẽ trả về giá trị khi:
 Một trong các mô tả file của tập {1,4,5} sẵn sàng để đọc
 Một trong các mô tả file của tập {2,7} sẵn sàng để ghi
 Một trong các mô tả file của tập {1,4,5} nhận ngoại lệ
 Sau khi đã hết 20 giây
45Network programming
Select(): dùng cho xuất nhập 
không đồng bộ
 Các tham số
 maxfdp1: số lượng tối đa các mô tả file mà hệ thống phải kiểm tra trạng 
thái
 readset, writeset, exceptset: tập các mô tả file mà hệ thống sẽ kiểm tra 
trạng thái sẵn sàng đọc, viết, và có ngoại lệ
 timeout: thời gian timeout đợi một trong các mô tả file trở nên sẵn sàng
 Kiểu dữ liệu fd_set data : 
 Biểu diễn tập các miêu tả file dưới dạng chuỗi integer, mỗi bit trong chuỗi 
ứng với một miêu tả file
#include #include 
int select(int maxfdp1, fd_set *readset, fd_set *writeset, 
fd_set *exceptset, const struct timeval *timeout);
Returns: positive count of ready descriptors, 
0 on timeout, –1 on error
46Network programming
Khi nào một socket ở trạng thái sẵn 
sàng đọc
 Khi số byte dữ liệu trong buffer của socket lớn hơn hoặc bằng 
kích thước tối thiểu (mặc định là 1)
 Chúng ta có thể thiết lập giá trị kích thước tối thiểu bằng tùy 
chọn SO_RCVLOWAT
 Khi một nửa đọc của kết nối bị đóng
 Kết nối TCP nhận được gói tin FIN
 Một thao tác đọc socket sẽ trả về giá trị 0 (i.e. EOF)
 Nếu socket là socket lắng nghe thì số lượng kết nối đã hoàn 
thành bắt tay ba bước trong hàng đợi lớn hơn 0
 Một lỗi socket đang chờ
 Một thao tác đọc socket sẽ trả về giá trị -1 với tập errno được 
gán giá trị tùy thuộc vào lỗi xảy ra
47Network programming
Khi nào một socket ở trạng thái sẵn 
sàng ghi?
 Khi số byte trống trong buffer gửi của socket lớn hơn hoặc bằng độ 
lớn tối thiểu (mặc định là 2048) và : 
 socket đang được kết nối
 socket không cần kết nối(e.g., UDP)
 Một nửa đọc của kết nối bị đóng 
 Một thao tác viết trên socket sẽ sinh ra tín hiệu SIGPIPE
 Một socket sử dụng kết nối non-blocking vừa hoàn thành bắt tay 3 
bước hay kết nối đó bị thất bại
 Một lỗi socket đang chờ
 Một thao tác viết trên socket đó sẽ trả về giá trị -1 cùng với 
tập errno set được gán giá trị của lỗi
48Network programming
Macros
 /* Xóa tất cả các bits trong fdset */
void FD_ZERO(fd_set *fdset); 
 /* Bật một bit ứng với fd trong fdset */
void FD_SET(inf fd, fd_set *fdset); 
 /* Tắt một bit ứng với fd trong fdset */
void FD_CLR(inf fd, fd_set *fdset);
 /* Kiểm tra xem bit ứng với fd trong fdset có
được bật lên hay không*/
Int FD_ISSET(inf fd, fd_set *fdset);
49Network programming
Cách thực thi máy chủ
1. Tạo ra socket lắng nghe tại một cổng dịch vụ. 
Gán socket này vào tập mô tả file xuất nhập dữ 
liệu
2. Sử dụng lệnh gọi select để chờ xuất nhập dữ 
liệu trên tập mô tả file của các sockets
3. Nếu socket lắng nghe sẵn sàng, gọi hàm 
accept để chấp nhận kết nối mới và nhận về 
một socket kết nối. 
4. Gán socket kết nối vào tập mô tả file xuất nhập 
dữ liệu
50Network programming
Cách thực thi máy chủ (2)
5. Nếu có socket kết nối sẵn sàng, gọi hàm 
đọc để đọc yêu cầu từ máy khách, xử lý yêu 
cầu và tạo thông báo trả lới. Gọi hàm ghi để 
gửi thông báo trả lời cho máy khách
6. Tiếp tục xử lý với bước 2 ở trên
51Network programming
Ví dụ - Máy chủ ECHO đơn tiến trình
/* TCPmechod.c - main, TCPechod */
/* include header files here */
#define QLEN 5 /*max. connection queue length */
#define BUFSIZE 4096
extern int errno;
int echo (int fd) /*echo data until end of file */
int errexit (const char *format, );
int passiveTCP (const char *service, int qlen);
52Network programming
/* main- concurrent TCP server for ECHO service */
int main(int argc, *argv[])
{
char *service = “echo”; /*service name or port number */
struct sockaddr_in fsin; /* the from address of a client */
int alen; /* length of a client’s address */
int msock; /* master server socket */
fd_set rfds; /* read file descriptor set */
fd_set afsd; /* active file descriptor set */
int fd;
/* check arguments - not detailed here*/
53Network programming
msock = passiveTCP (service, QLEN);
FD_ZERO (&afds);
FD_SET (msock, &afds);
while(1) {
memcpy(&rfds, &afds, sizeof(rfds));
if ( select (FD_SETSIZE, &rfds, (fd_set *) 0, 
(fd_set *) 0, (struct timeval *) 0) < 
0)
errexit (“select: %s\n”, strerror(errno));
54Network programming
if ( FD_ISSET (msock, &rfds)) {
int ssock;
alen = sizeof (fsin);
ssock = accept(msock,(struct sockaddr *)&fsin,
&alen);
if ( ssock < 0)
errexit (“accept: %s\n, strerror (errno));
FD_SET (ssock, &afds);
}
55Network programming
for ( fd = 0; fd < FD_SETSIZE; ++fd)
if (fd!=msock && FD_ISSET(fd, &rfds))
if (echo(fd) ==0 ) {
(void) close (fd);
FD_CLR (fd, &afds);
}
}
}
56Network programming
/* Echo - echo one buffer of data, returning byte 
count */
int echo (int fd)
{ 
char buf[BUFSIZE];
int cc;
cc = read (fd, buf, sizeof(buf));
if ( cc < 0 )
errexit(“echo read: %s\n”, strerror(errno));
if (cc && write(fd, buf, cc) < 0 )
errexit (“echo write: %s\n”, strerror(errno));
return cc;
}
57Network programming
Vấn đề của xử lý đồng thời, đơn tiến 
trình
 Xử lý đồng thời nhiều kết nối 
nhưng xử lý tuần tự các yêu cầu
=> Denial Of Service
            Các file đính kèm theo tài liệu này:
 ltm_bai_7_lap_trinh_may_chu_3366.pdf ltm_bai_7_lap_trinh_may_chu_3366.pdf