2008-11-26 19 views
6

Je suis en train de développer un programme de type FTP pour télécharger un grand nombre de petits fichiers sur un kit de développement Xbox 360 (qui utilise Winsock) et le porter sur Playstation3 (également un kit de développement). AUTANT QUE JE SACHE). Le programme utilise des sockets de style BSD (TCP). Les deux programmes communiquent avec le même serveur, en téléchargeant les mêmes données. Le programme itère sur tous les fichiers dans une boucle comme ceci:Différence entre sockets winsock et linux

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

sur la mise en œuvre Xbox 360, l'ensemble prend le téléchargement 01h27 et le temps écoulé entre le dernier envoi et première réception prend environ 14 secondes. Cela me semble assez raisonnable.

L'implémentation de Playstation3 nécessite 4:01 pour les mêmes données. Le goulot d'étranglement semble être entre le dernier envoi et le premier reçu, ce qui prend jusqu'à 3h43 de ce temps. Les temps de réseau et de disque sont tous les deux significativement inférieurs à la Xbox 360.

Ces deux devkits sont sur le même commutateur que mon PC, qui sert le service de fichier, et il n'y a aucun autre trafic sur ledit commutateur.

J'ai essayé de définir le drapeau TCP_NODELAY, ce qui n'a pas changé les choses de manière significative. J'ai également essayé de régler le SO_SNDBUF/SO_RCVBUF à 625KB, ce qui n'a pas non plus affecté de manière significative l'heure. Je suppose que la différence réside entre les implémentations de pile TCP/IP entre Winsock et Linux; Y at-il une option de socket que je pourrais définir pour que l'implémentation de Linux se comporte plus comme Winsock? Y at-il autre chose que je ne comptabilise pas?

La seule solution semble être de le réécrire afin qu'il envoie toutes les demandes de fichiers ensemble, puis les reçoit toutes.

Malheureusement, l'implémentation de Sony n'a pas l'option TCP_CORK, donc je ne peux pas dire si c'est la différence.

+0

Quel mode FTP utilisez-vous, passif ou actif? En outre, vous dites "le temps entre le dernier envoi et la première réception prend environ 14 secondes, ce qui me semble tout à fait raisonnable." Je suis surpris qu'attendre 14 secondes pour une réponse à une commande RETR est raisonnable, surtout quand il est plus long pour la PS3. – Alexander

Répondre

2

Vous voulez TCP_CORK. Cela empêchera l'envoi de trames partielles en augmentant le débit (au détriment de la latence) - tout comme le winsock.

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

Set v=0 pour rincer les cadres avant de recevoir:

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

Sur la plupart des systèmes Unix, vous pouvez améliorer votre débit plus loin en utilisant writev() ou sendfile() ...

1

Wireshark est votre ami, sniff le fil - regardez les paquets voir comment chacun est séquencé et voir si vous ne pouvez pas repérer la différence/problème.

Sur des liaisons à latence élevée, vous voulez vraiment vous assurer que vous tampon autant que possible en gardant chaque paquet TCP au maximum.

Envoyer coalesce est généralement une bonne idée. Il ne se déclenche que s'il y a plus d'une trame non acquittée mise en file d'attente du côté émission. En général, SEULEMENT désactivez cette fonctionnalité si vous savez ce que vous faites et si votre système fournit une mise en mémoire tampon complète. Sinon, il est certain que la désactivation affectera négativement les performances du système sur les réseaux à latence élevée.

Pour le tampon de débit le plus élevé, la démarcation doit être le facteur exact du chemin MTU.