Một client và server TCP đơn giản (tiếp tục)
Bắt đầu bằng cách xem xét send(). Khi bạn thực hiện một TCP send(), stack mạng hệ điều hành của bạn sẽ đối diện một
trong ba tình huống sau.
+ Dữ liệu có thể được chấp nhận ngay lập tức bởi stack mạng hệ thống địa phương, hoặc là vì card mạng ngay lập tức
tự do truyền hoặc là vì hệ thống dành chỗ để copy dữ liệu tới bộ nhớ đệm đi ra tạm thời để rằng chương trình của
bạn có thể tiếp tục chạy. Trong những trường hợp này, send() trả về ngay lập tức, và nó sẽ trả về độ dài chuỗi
dữ liệu khi nó trả về giá trị vì toàn bộ chuỗi đang được truyền.
+ Khả năng khác là rằng card mạng là bận rộn và rằng bộ nhớ đệm dữ liệu đi ra cho socket này là đầy và hệ thống không
thể – hoặc sẽ không phân bổ thêm không gian bộ nhớ hơn nữa. Trong trường hợp này, hành vi mặc định của send() đơn
giản phong tỏa , dừng chương trình của bạn cho đến khi dữ liệu có thể được chấp nhận cho truyền.
+ Có một khả năng khả năng cuối cùng, ngay lập tức: rằng bộ nhớ đệm đi ra là hầu như đầy, nhưng không hoàn toàn, và
nên phần dữ liệu cái bạn đang cố gắng gửi có thể ngay lập tức xếp hàng. Nhưng phần còn lại của khối dữ liệu sẽ phải
chờ. Trong trường hợp này, send() hoàn thành ngay lập tức và trả về số bytes được chấp nhận từ phần bắt đầu chuỗi
dữ liệu nhưng để lại phần còn lại của dữ liệu chưa được xử lí.
Vì khả năng cuối này, bạn không thể đơn giản gọi send() trên một socket dòng mà không kiểm tra giá trị trả về. Bạn
đã phải đặt lời gọi send() bên trong một loop cái trong trường hợp một truyền một phần, sẽ duy trì cố gắng gửi dữ liệu
còn lại cho đến khi toàn bộ chuỗi byte đã được gửi. Bạn sẽ đôi khi thấy cái này bộc lộ trong code liên mạng sử dụng
một loop như cái sau:
bytes_sent = 0
while bytes_sent < len(message):
message_remaining = message[bytes_sent:]
bytes_sent += s.send(message_remaining)