Professional Documents
Culture Documents
Bai 6 - Lap Trinh May Chu
Bai 6 - Lap Trinh May Chu
Network programming 1
Nội dung bài học
Network programming 2
Đặt vấn đề
Network programming 3
Phân loại máy chủ theo cách thức
cung cấp dịch vụ
Network programming 4
Máy chủ không kết nối
Network programming 5
Máy chủ hướng kết nối
n Máy chủ sử dụng giao thức TCP
q Sử dụng khái niệm kết nối trong truyền tin
n 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
n Đóng kết nối sau khi kết thúc truyền tin
n Ưu điểm
q Truyền tin tin cậy
n Nhược điểm
q Chi phí cao: phải tạo socket riêng cho từng kết nối với máy
khách
Network programming 6
Khái niệm xử lý tuần tự/xử lý đồng
thời
n Chương trình xử lý tuần tự
q Một tiến trình/một luồng điều khiển việc xuất nhập
dữ liệu
n Xử lý tuần tự từng yêu cầu của mỗi máy khách
q Dễ thực hiện
n Chương trình xử lý đồng thời
q Nhiều tiến trình/luồng điều khiển việc xuất nhập
và xử lý dữ liệu
q Các tiến trình/luồng thực hiện đồng thời
q Khó thực hiện
Network programming 7
Máy chủ xử lý tuần tự
n Tại mỗi thời điểm, xử lý một yêu cầu
q Đưa các yêu cầu mới vào một hàng đợi
n 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
n Dễ thực thi nhưng kém hiệu quả
q 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
Client1
Client2
Network programming 8
Cách thực hiện máy chủ xử lý tuần tự
Network programming 9
TCP server
socket()
Connection
request accept()
connect()
data (request)
write() read()
EOF
close() read()
close()
Network programming 10
Máy chủ xử lý đồng thời
n Có thể xử lý nhiều yêu cầu đến cùng một lúc
n Máy khách không cần đợi yêu cầu trước đó kết thúc
n 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
Client1
Client2
Network programming 11
Cách thực thi máy chủ xử lý đồng
thời
n Đa tiến trình
q Tạo ra nhiều tiến trình
q Mỗi tiến trình xử lý một yêu cầu của máy khách
n Đa luồng
q Tạo ra nhiều luồng
q Mỗi luồng xử lý một yêu cầu của máy khách
n Đa xuất nhập (I/O multiplex)
q Đơn tiến trình
q Xuất nhập dữ liệu tại nhiều socket cùng một lúc
q 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
Network programming 12
Xử lý đồng thời tốt trong trường hợp
nào?
n Trả lời một yêu cầu cần nhiều thời gian xuất/
nhập dữ liệu
q E.g. File transfer, Telnet, Web server,…
n Thời gian xử lý các yêu cầu của máy khách là
khác nhau lớn
n Máy chủ chạy trên một máy tính có nhiều bộ
vi xử lý
Network programming 13
Máy chủ xử lý đồng thời,
không kết nối, đa tiến trình
Network programming 14
Máy chủ xử lý đồng thời, không kết nối, đa
tiến trình
n Bước 1 tiến trình mẹ: Khởi tạo socket, gán
thông tin cho socket
Network programming 15
Máy chủ xử lý đồng thời, không kết nối (2)
n 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
Network programming 16
Máy chủ xử lý đồng thời,
hướng kết nối, đa tiến trình
Network programming 17
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?
Network programming 18
master
Server
slave1 slave2 slaven
application
processes
Network programming 20
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)
n Bước 1 tiến trình con: Nhận socket kết nối với máy
khách
n 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
n 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
Network programming 21
fork(): Tạo tiến trình mới
#include <unistd.h>
pid_t fork(void);
n Khởi tạo một tiến trình con chỉ khác tiến trình mẹ ở
PID và PPID
n Gọi một lần nhưng trả về 2 lần
q Trả về trên tiến trình mẹ với giá trị trả về là PID của tiến
trình con
q Trả về trên tiến trình con, với giá trị trả về là 0
n Lấy PID của tiến trình mẹ bằng hàm getppid()
Network programming 22
2 cách sử dụng điển hình với fork
Network programming 23
Ví dụ về máy chủ ECHO xử lý đồng thời, đa
tiến trình
n tcpserv02.c
Network programming 24
Chi tiết về xử lý đồng bộ
n Tiến trình mẹ
q đóng socket kết nối connfd của kết nối mới
q sử dụng socket chờ listenfd để tiếp tục chờ kết nối mới
q cung cấp dịch vụ echo (str_echo(connfd)) thông qua kết nối mới
n tiết tục sử dụng socket kết nối connfd cho đến khi thoát
ra (exit)
q Tiến trình con phải thoát ra (exit) sau khi đã thực hiện xong dịch
vụ
n Lệnh Exit được sử dụng để kết thúc tiến trình
n 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
Network programming 25
Xử lý đồng bộ với fork()
client Server(parent)
server
connection request listenfd
connect() connection
connfd
connection
fork()
Server (child)
Server(child)
listenfd
connfd
Network programming 26
Vấn đề tiến trình không kết thúc hoàn toàn
Network programming 27
Giải quyết vấn đề tiến trình không kết
thúc hoàn toàn như thế nào?
n 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)
n 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
n 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
Network programming 28
/* sig_chld - clean up zombie child */
void sig_chld(int signo){
int status;
while (wait3(&status, WNOHANG, (struct rusage
*) 0) >= 0)
/* empty */;
}
n 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
n 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
Network programming 29
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;
}
n 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
n Tùy chọn –1 để chỉ đợi tiến trình con thứ nhất
Network programming 30
Xử lý cuộc gọi hệ thống bị ngắt như
thế nào?
n Vấn đề:
q 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ị?
q 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”);
Network programming 31
Ví dụ về máy chủ ECHO xử lý đồng thời, đa
tiến trình
n tcpserv03.c
Network programming 32
Máy chủ hướng kết nối, xử
lý đồng thời, đơn tiến trình
Network programming 33
Tại sao lại xử lý đồng thời đơn tiến trình?
Network programming 34
Thực hiện xử lý đồng thời đơn tiến trình
như thế nào?
n 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
q Duy trì một tập các sockets
n 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
n Các socket khác sẽ ứng với các kết nối đến các máy
khách
Network programming 35
server Server
<---
application
process
Socket lắng
Operating <---
Socket kết nối ứng với system
nghe yêu cầu mỗi kết nối riêng biệt
kết nối
Network programming 36
Thực hiện xử lý đồng thời đơn tiến trình
như thế nào? (2)
n 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 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ý
n Sau đó các bước trên được lặp lại
n 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?
Network programming 37
Các mô hình xuất nhập dữ liệu
Network programming 38
Blocking I/O Model
application kernel
recvfrom system call no datagram ready
wait for
data
process
blocks in datagram ready
call to
copy datagram
recvfrom
copy data
from kernel
to user
return OK
process copy complete
datagram
Network programming 39
Nonblocking model
application kernel
system call
recvfrom no datagram ready
EWOULDBLOCK
system call
recvfrom no datagram ready wait for
EWOULDBLOCK data
process
recvfrom system call datagram ready
repeatedly
call recvfrom,
copy datagram
waiting for
an OK return copy data
from kernel
to user
return OK
process copy complete
datagram
Network programming 40
I/O Multiplexing Model
application kernel
system call
select no datagram ready
process blocks
in call to
select, waiting wait for
for one of data
possibly many return readable
sockets to datagram ready
become readable system call
recvfrom copy datagram
Network programming 41
Signal-driven I/O model
application kernel
sigaction system call
establish
SIGIO signal return
handler
process wait
continues for
executing signal data
deliver SIGIO
handler datagram ready
system call
recvfrom copy datagram
Network programming 42
Asynchronous I/O Model
application kernel
aio_read system call no datagram ready
return
wait for
data
process
datagram ready
continues
executing copy datagram
copy data
from kernel
to user
signal
handler deliver signal
copy complete
process specified in
datagram aio_read
Network programming 43
Hàm gọi select
n 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
q Không chỉ có socket
q Có thể thiết lập thời gian timeout tối đa
n Ví dụ, hàm select sẽ trả về giá trị khi:
q Một trong các mô tả file của tập {1,4,5} sẵn sàng để đọc
q Một trong các mô tả file của tập {2,7} sẵn sàng để ghi
q Một trong các mô tả file của tập {1,4,5} nhận ngoại lệ
q Sau khi đã hết 20 giây
Network programming 44
Select(): dùng cho xuất nhập
không đồng bộ
#include <sys/select.h>#include <sys/time.h>
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
n Các tham số
q 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
q 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ệ
q timeout: thời gian timeout đợi một trong các mô tả file trở nên sẵn sàng
n Kiểu dữ liệu fd_set data :
q 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
Network programming 45
Khi nào một socket ở trạng thái sẵn
sàng đọc
n 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)
q 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
n Khi một nửa đọc của kết nối bị đóng
q Kết nối TCP nhận được gói tin FIN
q Một thao tác đọc socket sẽ trả về giá trị 0 (i.e. EOF)
n 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
n Một lỗi socket đang chờ
q Một thao tác đọc socket sẽ trả về giá trị -1 với tập errno được
Network programming 46
Khi nào một socket ở trạng thái sẵn
sàng ghi?
n 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à :
q socket đang được kết nối
q socket không cần kết nối(e.g., UDP)
n Một nửa đọc của kết nối bị đóng
q Một thao tác viết trên socket sẽ sinh ra tín hiệu SIGPIPE
n 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
n Một lỗi socket đang chờ
q 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
Network programming 47
Macros
n /* Xóa tất cả các bits trong fdset */
void FD_ZERO(fd_set *fdset);
n /* Bật một bit ứng với fd trong fdset */
void FD_SET(inf fd, fd_set *fdset);
n /* Tắt một bit ứng với fd trong fdset */
void FD_CLR(inf fd, fd_set *fdset);
n /* 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);
Network programming 48
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
Network programming 49
Cách thực thi máy chủ (2)
Network programming 50
Ví dụ - Máy chủ ECHO đơn tiến trình
Network programming 51
/* 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;
Network programming 52
msock = passiveTCP (service, QLEN);
FD_ZERO (&afds);
FD_SET (msock, &afds);
while(1) {
memcpy(&rfds, &afds, sizeof(rfds));
Network programming 53
if ( FD_ISSET (msock, &rfds)) {
int ssock;
Network programming 54
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);
}
}
}
Network programming 55
/* 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;
}
Network programming 56
Vấn đề của xử lý đồng thời, đơn tiến
trình
nXử 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
Network programming 57