2008-11-26 44 views
6

Tôi đang phát triển một chương trình giống như FTP để tải xuống một số lượng lớn tệp nhỏ trên bộ nhớ Xbox 360 (sử dụng Winsock) và chuyển nó sang Playstation3 (cũng là một bộ giải mã và sử dụng linux) AFAIK). Chương trình sử dụng các ổ cắm kiểu BSD (TCP). Cả hai chương trình giao tiếp với cùng một máy chủ, tải xuống cùng một dữ liệu. Chương trình lặp qua tất cả các tệp trong một vòng lặp như sau:Sự khác biệt giữa các ổ khóa winsock và linux

for each file 
    send(retrieve command) 
    send(filename) 
    receive(response) 
    test response 
    receive(size) 
    receive(data) 

Khi thực hiện Xbox 360, toàn bộ quá trình tải xuống mất 1:27 và thời gian giữa lần gửi và lần gửi đầu tiên mất khoảng 14 giây. Điều này có vẻ khá hợp lý với tôi.

Việc triển khai Playstation3 mất 4,01 cho cùng một dữ liệu. Nút cổ chai có vẻ là giữa lần gửi cuối cùng và lần nhận đầu tiên, chiếm tới 3:43 thời gian đó. Thời gian mạng và ổ đĩa đều nhỏ hơn đáng kể so với Xbox 360.

Cả hai thiết bị này đều có cùng công tắc như PC của tôi, tệp này phân phối và không có lưu lượng truy cập nào khác trên chuyển đổi được cho biết.

Tôi đã thử đặt cờ TCP_NODELAY, điều này đã không thay đổi đáng kể mọi thứ. Tôi cũng đã thử cài đặt SO_SNDBUF/SO_RCVBUF thành 625KB, điều này cũng không ảnh hưởng đáng kể đến thời gian.

Tôi giả sử rằng sự khác biệt nằm giữa việc triển khai ngăn xếp TCP/IP giữa Winsock và linux; là có một số tùy chọn ổ cắm mà tôi có thể thiết lập để làm cho việc thực hiện Linux cư xử giống như Winsock? Có cái gì khác tôi không kế toán?

Giải pháp duy nhất có vẻ là viết lại nó để nó gửi tất cả các yêu cầu tệp cùng nhau, sau đó nhận tất cả chúng.

Thật không may, việc triển khai của Sony không có tùy chọn TCP_CORK, vì vậy tôi không thể nói nếu đó là sự khác biệt.

+0

Chế độ FTP nào bạn đang sử dụng, thụ động hoặc đang hoạt động? Ngoài ra, bạn nói "thời gian giữa lần gửi cuối cùng và lần nhận đầu tiên mất khoảng 14 giây. Điều này có vẻ khá hợp lý với tôi". Tôi ngạc nhiên rằng chờ đợi 14 giây cho một câu trả lời cho một lệnh RETR là hợp lý, đặc biệt là khi nó còn cho PS3. – Alexander

Trả lời

2

Bạn muốn TCP_CORK. Nó sẽ ngăn chặn một phần khung được gửi thông lượng ngày càng tăng (tại các chi phí của độ trễ) - giống như winsock.

int v,vlen; 
v=1; vlen=sizeof(v); 
setsockopt(fd, IPPROTO_TCP, TCP_CORK, &v, &vlen); 

Set v=0 để tuôn ra những khung hình trước khi nhận:

int v,vlen; 
v=0; vlen=sizeof(v); 
setsockopt(fd, IPPROTO_TCP, TCP_CORK, &v, &vlen); 

Trên hầu hết các unixes bạn có thể cải thiện thông lượng của bạn hơn nữa bằng cách sử dụng writev() hoặc sendfile() ...

1

Wireshark là bạn của bạn, sniff dây - nhìn vào các gói dữ liệu xem cách mỗi trình tự được sắp xếp theo trình tự và xem bạn có thể phát hiện sự khác biệt/vấn đề không.

Trên các liên kết có độ trễ cao, bạn thực sự muốn đảm bảo rằng bạn đã lưu bộ nhớ càng nhiều càng tốt để giữ cho mỗi gói TCP tối đa.

Gửi kết hợp thường là một ý tưởng hay. Nó chỉ kích hoạt khi có nhiều hơn một khung không được trả lời được xếp hàng đợi ở phía gửi. Thông thường, bạn nên tắt tính năng này CHỈ nếu bạn biết mình đang làm gì và hệ thống của bạn cung cấp tính năng đệm toàn diện nếu không tắt nó chắc chắn sẽ làm giảm hiệu suất hệ thống hiệu quả trên các mạng có độ trễ cao.

Đối với phân đoạn đệm thông lượng cao nhất nên là các yếu tố chính xác của đường dẫn MTU.

Các vấn đề liên quan