2011-04-12 3 views
0

Edit: Il s'est avéré être un problème avec mon adaptateur Ethernet intégré. Fonctionne bien maintenant. Merci tout le monde.TCP Unix send() très lent C

Lorsque j'envoie un fichier via une socket tcp, le transfert prend beaucoup de temps (~ 4 secondes pour 1,5 m). Le même fichier se déplace presque instantanément sur tftp. Je sais que tftp utilise UDP, ce qui devrait être plus rapide, mais je pense toujours que mon transfert est trop lent. Je suis connecté 100Mbps en semi-duplex, à travers un câble croisé. L'expéditeur est UNIX et le destinataire est .Net sur Windows TcpClient.

Alors, qu'est-ce que tout le monde pense? Ai-je besoin d'un meilleur code C? Y at-il peut-être quelque chose qui ne va pas avec le réseau?

Voici mon code C:

int main(void) 
{ 
    //some initializing stuff 
    int AcceptSocket, ClientRecvSocket; 

    alen = sizeof(fsin); 
    int AcceptSocket = passiveTCP("20075", 10); 
    //Wait for client connections, and spawn a new thread to communicate with each one 
    pszRecvBuf = malloc((size_t) BUFSIZE); 
    while (1) 
    { 
     ClientRecvSocket = accept(AcceptSocket, &fsin, &alen); 
     printf("\nDebug: Accepted Connection\n"); 
     if (ClientRecvSocket < 0) 
     { 
      sprintf(szStr, "Error accepting client connection : %d", 
        ClientRecvSocket); 
      perror(szStr); 
     } 
     else 
     { 
      printf("\nDebug: Starting Thread\n"); 
      ThreadStatus = pthread_create(&ClientThread, NULL, ClientRecv, 
        (void *) &ClientRecvSocket); 
      pthread_join(ClientThread, NULL); 
     } 
    } 
} 

void *ClientRecv(void *ClientSocket) 
{ 
    pthread_setcanceltype(PTHREAD_CANCEL_ASYNCHRONOUS, NULL); 
    int Socket = *(int *) ClientSocket; 

    unsigned char *file_buffer; 
    file_buffer = malloc(1572864 * sizeof(unsigned char)); 

    //set file data to something 

    SendLen = send(Socket, file_buffer, 1572864 * sizeof(unsigned char), 0); 
    shutdown(Socket, SHUT_RDWR); 
    free(file_buffer); 
} 
int passiveTCP(char *service, int qlen) 
{ 
    return passivesock(service, "tcp", qlen); 
} 
+2

'passiveTCP',' AcceptSocket' etc sont tous non standard. Nous ne pouvons même pas commencer à aborder ce problème. –

+0

AcceptSocket est un int. Je n'ai pas réalisé que passiveTCP n'est pas standard. – dunecat

+1

Avant de regarder votre code, vous devriez probablement utiliser quelque chose comme 'netcat', ou même' ftp' pour vous assurer que votre connexion réseau n'est pas en cause. Les connexions semi-duplex peuvent être * difficiles * ... – thkala

Répondre

1

un coup d'oeil, regarder, dans votre fonction ClientRecv, vous consommez trop de ressources ...

unsigned char *file_buffer; 
file_buffer = malloc(1572864 * sizeof(unsigned char)); 

Vous êtes allouer de la mémoire pour cela, mais où est-il allé à .... devrait essayer de libérer le pointeur vers ce tampon ....

Comme une question d'intérêt pour servir et aider les autres, est-ce une sorte de wrappe r cadre que vous utilisez et s'il vous plaît spécifier quel type .... car je soupçonne fortement que c'est un logiciel non standard que vous utilisez - peut-être que le logiciel a certains "problèmes"?

+0

Je libère la mémoire, c'est une version simplifiée de mon code. Je n'utilise aucune sorte de wrapper que je connaisse. – dunecat

+1

Attention à montrer les internes de ces enveloppes, comme ce qui est 'PassiveTCP', ce qui est AcceptSocket/ClientRecvSocket ... ils sonnent un peu compliqué ... et non standard .... – t0mm13b

+0

Aussi, dans ce cas, si vous dites vous libérez la mémoire, s'il vous plaît modifiez votre question pour souligner cela afin de ne pas tromper les autres en leur faisant perdre leur temps en répondant aux mêmes questions ... "Je ne vois pas libre là-dedans ..." etc – t0mm13b

0

Essayez plutôt de connecter le mode duplex intégral.

Étant donné que TCP requiert un accusé de réception pour (approximativement) chaque paquet transmis, votre liaison semi-duplex devra arrêter d'émettre pour gérer la réception de ces ACK. Cela pourrait se manifester par des collisions, provoquant une perte de paquets et finissant par déclencher les contrôles d'encombrement de TCP.

+0

uClinix que j'utilise ne coopère pas avec mes demandes de duplex intégral. – dunecat

+0

L'entrée WP allemande pour "Full-duplex Ethernet" indique que si une extrémité de la connexion utilise la négociation automatique alors que l'autre extrémité applique le mode duplex intégral, la fin de l'auto-négociation ne détecte que le mode semi-duplex. collisions. – Philip

+0

@DuneCat: Doit indiquer uClinix dans votre question pour le rendre encore plus clair et attirer quelqu'un qui connaît uClinix à votre question .... – t0mm13b