2010-06-09 6 views
2

serveur:
VxWorks 6.3
appelle la prise habituelle, se lient, écouter, puis:tcp/ip accepter ne pas retourner, mais le client ne

for (;;) 
{ 
    client = accept(sfd,NULL,NULL); 
    // pass client to worker thread 
} 

client:
.NET 2.0
constructeur TcpClient pour se connecter au serveur qui prend la chaîne hostname et int port, comme:

Ceci fonctionne bien lorsque le s erver est compilé et exécuté dans Windows (natif C++).

Par intermittence, le constructeur de TcpClient renvoie l'instance, sans émettre d'exception, mais l'appel accepté dans vxWorks ne retourne pas avec le client fd. tcpstatShow indique qu'aucune acceptation n'a eu lieu.

Qu'est-ce qui pourrait faire que le constructeur TcpClient (qui appelle 'Connect') retourne l'instance, alors que l'appel accepté sur le serveur ne revient pas? Il semble être lié à ce que fait le système en arrière-plan - il semble plus probable que ce problème survienne lorsque le serveur est occupé à conserver des données à clignoter ou un partage NFS lorsque le client tente de se connecter, mais cela peut arriver n'est pas aussi.

J'ai essayé d'ajuster la priorité du thread en cours d'exécution accepter
J'ai regardé la taille de la file d'attente dans «écouter». Il y a assez.
Le nombre total de descripteurs de fichiers disponibles devrait être suffisant (ne l'avez pas encore validé, cependant, la première chose le matin)

+0

Avez-vous réussi à comprendre ce qui se passait ici? – Default

+0

Non. - J'ai une demande de support ouverte avec WindRiver (vxworks) à ce sujet. J'ai fait la trace de wireshark, et quand cela s'est produit, j'ai vu le bon SYN et SYN, ACK, donc Windows a fait la bonne chose. Cela ne s'est jamais produit sur notre cible déployée, ce qui aurait pu être un coup de chance, c'est pourquoi nous avons vécu avec ça pendant si longtemps ... la trame IP précédente était une RST, ACK sur le flux de données précédent - c'est peut-être le problème, côté vxworks ... les ports étaient> 1000 – paquetp

+0

Lorsque vous utilisez un constructeur sans paramètre, puis appelez Connect (addr, port). Est-ce que ça marche? – Kugel

Répondre

1

serait-il possible pour vous de publier un wireshark/netmon de ce qui se passe sur le fil?

+0

Appuyé. Cela permettra d'isoler si le problème est du côté du client ou du serveur, en réduisant de moitié le nombre de lieux à regarder. Cela aurait-il dû être un commentaire, au lieu d'une réponse? – Slartibartfast

+0

Troisième. Wireshark serait très utile feedback – Default

+0

cela ressemble à la façon dont je vais aller ... ne voulait pas, j'espérais que quelqu'un ne ferait que mentionner quelque chose comme - 'oh, TcpClient ne fonctionne pas avec vxWorks, vous avez vous ramène le Socket à l'intérieur et mets le drapeau xyz ou quelque chose '... eh bien. – paquetp

0

Il peut y avoir beaucoup de raisons, cependant nous ne saurons pas à moins que nous puissions obtenir plus d'information de le côté serveur et client. Est-ce qu'il jette des erreurs? Une liste d'erreurs TCP/IP peut être trouvée ici Windows Socket Error. Du côté du serveur, attrapez-vous des exceptions? Peut-être que vous pouvez essayer de fermer la connexion (avec un retard de 1 seconde) après une erreur?

+0

C'est exactement le problème - il n'y a pas d'erreur! Le côté client renvoie joyeusement l'instance TcpClient, mais le serveur ne revient jamais d'accepter. Côté serveur, il n'y aura pas d'exception, car les bibliothèques de socket sont des bibliothèques C, pas C++. J'en arrive au point de tenter d'écrire mon propre protocole pour confirmer l'acceptation en envoyant immédiatement des données au client et si je ne l'obtiens pas après un certain temps, j'essaye de me connecter à nouveau ... mais quel kludge ce serait! – paquetp

0

Est-il possible de lier le serveur sur un autre port et de voir s'il y est accepté? Si le client revient, cela sonne comme s'il acceptait quelque chose sur votre serveur. Je ne connais pas vxworks, mais dans Windows, vous devriez toujours essayer de ne pas lier à quoi que ce soit en dessous de 1000.

0

L'appel de votre serveur accept() ne semble pas correct. L'appel Posix accept() que je connais a:

int accept(int sockfd, struct sockaddr *addr, socklen_t *addrlen); 

*addr est un pointeur requis qui sont écrites sur si l'appel fonctionne-en effet, l'un des états d'échec de l'appel est:

[EFAULT] The address parameter is not in a writable part of the user address space. 

Je n'ai pas fait de programmation de socket Windows, mais je comprends qu'il est compatible POSIX, et le guide de Beej ne mentionne aucune exception pour Windows pour accept(), donc cela devrait toujours s'appliquer. Quelque chose de pertinent, l'appel de Python accept() also 'returns' the address field (je dis un peu car Python a fait de son mieux pour émuler l'API de réseautage C comme cela avait du sens.)

Je suggère de vérifier errno et en utilisant perror après l'appel accept dans le serveur, pour voir si [EFAULT] est réglé (il sera également vous informer si vous manquiez de descripteurs, comme errno se prépare à [EMFILE] ou [ENFILE])

Si ne correspond pas à, utilisez ncat, en tant que serveur ou client, pour étudier plus avant. Je le ferais avec -vv puisque vous voulez savoir exactement quand les connexions sont faites, ce qui est envoyé etcetera.

+0

les sockets que j'utilise ne font pas partie de la conformité POSIX (leurs sockets de domaine non unix), ce sont des sockets internet, ou des sockets 'BSD', qui ne font pas partie de POSIX. le deuxième paramètre de accept est facultatif selon http://opengroup.org/onlinepubs/007908799/xns/accept.html. Vous pouvez passer NULL si vous ne vous souciez pas de l'adresse réelle du client. Et si ce n'était pas autorisé, il reviendrait avec une erreur, ce qui n'est pas le cas. – paquetp

Questions connexes