2008-11-26 5 views
6

Я разрабатываю FTP-программу для загрузки большого количества небольших файлов на Xbox 360 devkit (который использует Winsock) и переносит его на Playstation3 (также devkit и использует linux НАСКОЛЬКО МНЕ ИЗВЕСТНО). В программе используются сокеты BSD-стиля (TCP). Обе программы общаются с одним и тем же сервером, загружая одни и те же данные. Программа перебирает все файлы в цикле, как это:Разница между winsock и linux-сокетами

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

О реализации Xbox 360, вся загрузка занимает 1:27, а время между последними и отправками первыми получить занимает около 14 секунд. Это кажется мне вполне разумным.

Реализация Playstation3 занимает 4:01 для тех же данных. Узкое место, кажется, находится между последней отправкой и первым получением, которое занимает 3:43 того времени. Время работы сети и диска значительно меньше, чем у Xbox 360.

Оба этих devkits находятся на том же коммутаторе, что и мой компьютер, который обслуживает файл, и на этом коммутаторе нет другого трафика.

Я пробовал установить флаг TCP_NODELAY, который существенно не изменил ситуацию. Я также попытался установить SO_SNDBUF/SO_RCVBUF на 625 КБ, что также существенно не повлияло на время.

Я предполагаю, что разница между реализациями стека TCP/IP между Winsock и linux; есть ли опция сокета, которую я мог бы установить, чтобы сделать реализацию linux более похожим на Winsock? Есть ли что-то еще, что я не учитываю?

Единственное решение, похоже, состоит в том, чтобы переписать его так, чтобы он отправлял все запросы файла вместе, а затем получил их все.

К сожалению, реализация Sony не имеет опции TCP_CORK, поэтому я не могу сказать, является ли это разницей.

+0

Какой режим FTP вы используете, пассивный или активный? Также вы говорите: «Время между последней отправкой и первым получением занимает около 14 секунд. Это кажется мне вполне разумным». Я удивлен, что ждать 14 секунд для ответа на команду RETR является разумным, особенно когда это больше для PS3. – Alexander 2008-11-27 16:50:40

ответ

2

Вы хотите TCP_CORK. Это предотвратит передачу частичных кадров из-за увеличения пропускной способности (за счет латентности) - точно так же, как winsock.

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

Набор v=0 промывать кадры до приема:

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

На большинстве Unixes вы можете улучшить свою пропускную способность за счёт использования writev() или sendfile() ...

1

Wireshark является вашим другом, сопение провод - посмотрите на пакеты, как каждый из них будет упорядочен, и посмотрите, не можете ли вы определить разницу/проблему.

В каналах с высокой задержкой вы действительно хотите убедиться, что вы буксируете как можно больше, сохраняя каждый TCP-пакет.

Отправить coalesce является обычной идеей. Это срабатывает только тогда, когда на стороне отправки имеется более одного неподтвержденного фрейма. Как правило, вы должны ТОЛЬКО отключить эту функцию, если вы знаете, что делает, и ваша система обеспечивает полную буферизацию, в противном случае это может негативно повлиять на производительность системы в сетях с высокой задержкой.

Для максимальной пропускной способности буфер демарка должен быть точными факторами пути MTU.

 Смежные вопросы

  • Нет связанных вопросов^_^