Kích thước gói tối đa cho kết nối TCP


196

Kích thước gói tối đa cho kết nối TCP là bao nhiêu hoặc làm cách nào tôi có thể nhận được kích thước gói tối đa?


24
TCP dựa trên luồng. Có một lý do cụ thể mà bạn lo lắng về các gói riêng lẻ không?
Matti Virkkunen

27
Bởi vì các lớp bên dưới là gói dựa trên ... Thực hiện điển hình -> Lớp 1 - Ethernet PHY, Lớp 2 - Ethernet MAC (Định nghĩa gói MAC, Lớp 3 - Giao thức Internet (Định nghĩa gói IP), Lớp 4 - TCP (Giao thức điều khiển truyền ) - Sử dụng dịch vụ dựa trên gói bên dưới nó.

2
Không có thứ gọi là 'gói TCP'. Có các phân đoạn TCP , có độ dài được mô tả bằng một từ 32 bit và chúng được chứa trong hoặc trên các gói IP , có độ dài được mô tả bằng 16 bit. Ngoài ra còn có khung Ethernet, chứa tất cả những thứ này. Những điều này bạn đang hỏi về? Trong mọi trường hợp nếu bạn đang sử dụng TCP, bạn không phải lo lắng về bất kỳ vấn đề nào trong số đó theo bất kỳ cách nào: TCP và IP sẽ chăm sóc tất cả cho bạn.
Hầu tước Lorne

Câu trả lời:


178

Giới hạn tuyệt đối về kích thước gói TCP là 64K (65535 byte), nhưng trên thực tế, nó lớn hơn nhiều so với kích thước của bất kỳ gói nào bạn sẽ thấy, vì các lớp thấp hơn (ví dụ ethernet) có kích thước gói thấp hơn.

Ví dụ, MTU (Đơn vị truyền tối đa) cho Ethernet là 1500 byte. Một số loại mạng (như Token Ring) có MTU lớn hơn và một số loại có MTU nhỏ hơn, nhưng các giá trị được cố định cho từng công nghệ vật lý.


15
"Nhưng các giá trị được cố định cho từng công nghệ vật lý" - điều này không đúng. Ethernet từng có MTU tối đa 1500, nhưng bạn có thể sử dụng mức thấp hơn. Với sự ra đời của khung jumbo, không có mức tối đa được chỉ định thực sự và mức tối đa khác nhau tùy thuộc vào phần cứng và trình điều khiển.
WhirlWind

4
@Whirl: đúng, chúng có thể cấu hình được, nhưng nói chung chúng không có; "cấu hình" là chủ quan bởi vì người ta sẽ phải đi sâu vào kernel để làm như vậy. Đó không phải là thứ mà người ta có thể sửa đổi ở cấp ứng dụng, đó là nơi mà OP dường như đang ở.
Ether

3
@HiroProtagonist: 1500 là tối đa, vì vậy có 600 là không đáng ngạc nhiên.
Nicolas Raoul

28
Tại sao lại là giới hạn 64K (65535 byte)? Bởi vì thuộc tính Kích thước cửa sổ trong TCP Header chỉ có 16 bit. Tôi chỉ muốn đề cập, có thể giúp ai đó đôi khi ..... câu trả lời tuyệt vời btw @Ether!
Cacho Santa

2
Ngoài ra, có thể tăng nó lên bằng cách sử dụng tỷ lệ cửa sổ. Trong trường hợp đó, tối đa là 1 GiB
Martin Melka

86

Đây là một câu hỏi xuất sắc và tôi thực sự gặp phải vấn đề này rất nhiều trong công việc. Có rất nhiều câu trả lời "đúng về mặt kỹ thuật" như 65k và 1500. Tôi đã thực hiện rất nhiều công việc viết giao diện mạng và sử dụng 65k là ngớ ngẩn, và 1500 cũng có thể khiến bạn gặp rắc rối lớn. Công việc của tôi diễn ra trên rất nhiều phần cứng / nền tảng / bộ định tuyến khác nhau và thành thật mà nói, nơi tôi bắt đầu là 1400 byte. Nếu bạn CẦN hơn 1400 bạn có thể bắt đầu tiến lên, bạn có thể đến 1450 và đôi khi đến 1480? Nếu bạn cần nhiều hơn thế thì tất nhiên bạn cần chia thành 2 gói, trong đó có một số cách làm rõ ràng ..

Vấn đề là bạn đang nói về việc tạo gói dữ liệu và viết nó ra thông qua TCP, nhưng tất nhiên có dữ liệu tiêu đề được xử lý và cứ thế, vì vậy bạn có "hành lý" đưa bạn đến 1500 hoặc hơn thế nữa .. và cả rất nhiều phần cứng có giới hạn thấp hơn.

Nếu bạn "đẩy nó", bạn có thể nhận được một số điều thực sự kỳ lạ đang diễn ra. Dữ liệu bị cắt, rõ ràng hoặc bị mất dữ liệu mà tôi hiếm khi thấy. Dữ liệu bị hỏng cũng hiếm khi nhưng chắc chắn không xảy ra.


Tại sao các yêu cầu GET trung bình khoảng 600 Byte?

10
Ý bạn là 64K chứ không phải 65K. Tôi không biết ý của bạn là 'nơi tôi bắt đầu là 1400 byte'. Bạn không phải lo lắng về kích thước gói trong API TCP. Nó quan tâm đến việc xác định và quan sát MTU đường dẫn. Không có lý do tại sao bạn không thể viết 2G trong một send()nếu nó thuận tiện.
Hầu tước Lorne

19
Bạn 1480'ishnên là 1460. Tiêu đề IP và tiêu đề TCP chiếm tối thiểu 20 byte mỗi cái (trừ khi các trường tiêu đề tùy chọn được sử dụng) và do đó, tối đa cho Ethernet (khung không phải Jumbo) là 1500 - 20 -20 = 1460.
Eugene Beresovsky

2
Tôi đã thấy qua wireshark rằng một máy chủ gửi các gói lớn (hơn 1400 byte) và máy khách nhận được nó tách rời như một vài gói tối đa 1400 byte. ai chịu trách nhiệm cho việc tháo gỡ gói tin? @Nektario ...?
inbaly

2
@EugeneBeresovsky cũng tốt với các tiêu đề tùy chọn có thêm + 40 byte nữa, nhưng nó có thể thay đổi nên 1420 dường như là giới hạn. với gợi ý 1400 bạn sẽ có được một chút đệm. Tôi sẽ đi với 1408 vì nó chia hết cho 128
Garet Claborn

22

Ở cấp độ ứng dụng, ứng dụng sử dụng TCP làm giao thức hướng luồng. Lần lượt TCP có các phân đoạn và tóm tắt các chi tiết làm việc với các gói IP không đáng tin cậy.

TCP giao dịch với các phân đoạn thay vì các gói. Mỗi phân đoạn TCP có số thứ tự được chứa trong tiêu đề TCP. Dữ liệu thực tế được gửi trong một phân đoạn TCP là biến.

Có một giá trị cho gotockopt được hỗ trợ trên một số HĐH mà bạn có thể sử dụng được gọi là TCP_MAXSEG, lấy ra kích thước phân đoạn TCP tối đa (MSS). Nó không được hỗ trợ trên tất cả các hệ điều hành.

Tôi không chắc chắn chính xác những gì bạn đang cố gắng thực hiện nhưng nếu bạn muốn giảm kích thước bộ đệm đã sử dụng, bạn cũng có thể xem xét: SO_SNDBUF và SO_RCVBUF.


Tôi tự hỏi nếu bạn có thể sử dụng TCP như một hàng đợi tin nhắn nếu bạn có thể phù hợp với tất cả các tin nhắn của bạn trong một gói TCP lớn?
CMCDragonkai


4

Không có gói nào trong TCP API.

Có các gói trong các giao thức cơ bản thường xuyên, như khi TCP được thực hiện qua IP, điều mà bạn không quan tâm, bởi vì chúng không liên quan gì đến người dùng ngoại trừ việc tối ưu hóa hiệu suất rất tinh vi mà bạn có thể không quan tâm (theo xây dựng câu hỏi).

Nếu bạn hỏi số byte tối đa bạn có thể có send()trong một lệnh gọi API là bao nhiêu thì đây là cài đặt và cài đặt phụ thuộc. Bạn thường gọi send () cho các khối lên đến vài kilobyte và luôn sẵn sàng để hệ thống từ chối chấp nhận hoàn toàn hoặc một phần, trong trường hợp đó, bạn sẽ phải quản lý việc chia tách thành các phần nhỏ hơn để đưa dữ liệu của mình vào API gửi () TCP.


8
TCP có các gói, cũng như một tiêu đề gói, một phần trong đó chồng lên tiêu đề IP. Chỉ vì bạn không nên thấy nó không có nghĩa là nó không tồn tại. TCP luôn được thực hiện qua IP. Bạn không thể làm điều đó mà không có IP vì các tiêu đề chồng chéo.
WhirlWind

23
@WhirlWind TCP có các phân đoạn. IP có các gói.
Hầu tước Lorne

1
TCP có các phân đoạn (hoặc gọi chúng là các gói, nó ổn). API TCP không có gói.
Pavel Radzivilovsky

13
@NathanLong Tác hại là bạn gây nhầm lẫn không cần thiết. TCP có các phân đoạn, UDP có datagram, IP có các gói, Ethernet có khung, ...
Hầu tước Lorne

1
@Chexxor Vậy bạn sẽ sử dụng ngôn ngữ nào để mô tả các phân đoạn TCP bên trong các gói IP bên trong các khung Ethernet? Không cần thiết phải nhầm lẫn vấn đề bằng cách sử dụng cùng một thuật ngữ cho những thứ khác nhau, khi các tác giả của những điều này đã gặp rất nhiều rắc rối để sử dụng các thuật ngữ khác nhau.
Hầu tước Lorne

3

Nói chung, điều này sẽ phụ thuộc vào giao diện mà kết nối đang sử dụng. Bạn có thể có thể sử dụng ioctl () để lấy MTU và nếu đó là ethernet, bạn thường có thể nhận được kích thước gói tối đa bằng cách trừ kích thước của tiêu đề phần cứng từ đó, là 14 cho ethernet không có Vlan.

Đây chỉ là trường hợp nếu MTU ít nhất là lớn trên toàn mạng. TCP có thể sử dụng phát hiện MTU đường dẫn để giảm MTU hiệu quả của bạn.

Câu hỏi là, tại sao bạn quan tâm?


6
Điều đó sẽ chỉ giúp bạn có kích thước gói tối đa trên liên kết đầu tiên. Theo tôi biết, bất kỳ nút nào khác dọc theo tuyến đường đều được phép không thích các gói lớn và nó có thể bị chia tách ở bất kỳ đâu dọc theo đường dẫn.
Matti Virkkunen

Vâng, đó là sự thật ... vì vậy câu hỏi của bạn là tốt - tại sao bạn muốn điều này?
WhirlWind

Tôi muốn truyền video / hình ảnh qua kết nối lan
Alexa

1
Vì TCP được định hướng theo luồng, tại sao điều này lại quan trọng?
WhirlWind

3

Nếu bạn sử dụng máy Linux, "ifconfig eth0 mtu 9000 up" là lệnh đặt MTU cho giao diện. Tuy nhiên, tôi phải nói rằng, MTU lớn có một số nhược điểm nếu việc truyền mạng không ổn định và nó có thể sử dụng nhiều bộ nhớ không gian kernel hơn.


3

Có vẻ như hầu hết các trang web trên internet sử dụng 1460 byte cho giá trị của MTU. Đôi khi, nó là 1452 và nếu bạn đang sử dụng VPN, nó sẽ giảm nhiều hơn cho các tiêu đề IPSec.

Kích thước cửa sổ mặc định thay đổi khá nhiều lên đến tối đa 65535 byte. Tôi sử dụng http://tcpcheck.com để xem các giá trị IP nguồn của riêng tôi và để kiểm tra xem các nhà cung cấp Internet khác đang sử dụng cái gì.


2

Một giải pháp có thể là đặt tùy chọn ổ cắm TCP_MAXSEG ( http://linux.die.net/man/7/tcp ) thành giá trị "an toàn" với mạng bên dưới (ví dụ: được đặt thành 1400 để an toàn trên ethernet) và sau đó sử dụng một bộ đệm lớn trong cuộc gọi hệ thống gửi. Bằng cách này, có thể có các cuộc gọi hệ thống ít tốn kém hơn. Kernel sẽ phân chia dữ liệu để khớp với MSS.

Bằng cách này, bạn có thể tránh dữ liệu bị cắt và ứng dụng của bạn không phải lo lắng về bộ đệm nhỏ.


2

Kích thước gói cho cài đặt TCP trong giao thức IP (Ip4). Đối với trường này (TL), 16 bit được phân bổ, theo đó kích thước tối đa của gói là 65535 byte: Chi tiết giao thức IP

Khi sử dụng trang web của chúng tôi, bạn xác nhận rằng bạn đã đọc và hiểu Chính sách cookieChính sách bảo mật của chúng tôi.
Licensed under cc by-sa 3.0 with attribution required.