2010-02-12 3 views
1

est-il possible d'avoir plusieurs threads envoyant sur le même socket? y aura-t-il un entrelacement des flux ou le bloc socket sur le premier thread (en supposant tcp)? La majorité des opinions que j'ai trouvées semble mettre en garde contre le fait de le faire pour des peurs évidentes d'entrelacement, mais j'ai aussi trouvé quelques commentaires qui disent le contraire. sont des craintes d'entrelacement un report de winsock1 et sont-ils bien fondés pour winsock2? est-il un moyen d'installer un socket winsock2 qui permettrait le manque de synchronisation locale?winsock 2. sécurité des threads pour les envois simultanés. tcp

deux des opinions contraires ci-dessous ... qui a raison?

commentaire 1

« implémentations Winsock 2 doivent être thread complètement sûr. Simultanée lecture/écriture sur différents threads doivent réussir ou échouer avec WSAEINPROGRESS, en fonction du réglage du drapeau chevauchée lorsque la socket est créée. Quoi qu'il en soit par défaut, les sockets superposés sont créés, donc vous n'avez pas à vous en préoccuper.Veillez à ne pas utiliser NT SP6, si vous utilisez SP6a, ça devrait aller!

source

commentaire 2

« La même DLL ne sont pas accessibles par de multiples processus comme l'introduction de Windows 95. Chaque processus obtient sa propre copie du segment de données accessible en écriture pour la DLL. le modèle « tous les processus partagent » était l'ancien modèle Win16, ce qui est heureusement tout à fait mort et enterré maintenant ;-) »

source

avec impatience vos commentaires! jim

~ edit1 ~ pour clarifier ce que je veux dire par entrelacement. thread 1 envoie le msg "Bonjour" thread 2 envoie le msg "monde!". destinataire reçoit: "Hwoel lorld!". cela suppose que les deux messages n'ont PAS été envoyés dans une boucle while. Est-ce possible?

+0

Je suis sûr que l'entrelacement (terme old-school pourrait s'apparenter à un multiplexage) de cette manière est possible. Mais je ne suis pas sûr de vouloir assumer cette tâche. Votre récepteur devrait savoir comment les "pièces du puzzle" doivent être remises ensemble. – IAbstract

+0

salut dboarman, rgt. Je n'essaie pas d'y arriver, j'essaie de l'éviter. ce que je voulais dire par la question, 'est-ce possible?', était, 'est-il réellement physiquement possible pour winsock2 d'autoriser ce genre à mélanger plusieurs appels envoyés sur le même socket?' Comme vous pouvez le voir à partir du premier commentaire de ma question, l'individu cité semble dire que c'est impossible, par quoi le thread appelant la fonction d'envoi essayant de faire cela échouerait avec WSAEINPROGRESS. difficile de poser la question (et de répondre aussi) sans penser au design, mais j'essaie de le comprendre à partir d'un niveau plus bas. Merci. – jim

+0

la nature de tcp ne permettrait pas ... un envoi sur * un thread * se produit spécifiquement sur * ce * thread. Si vous pompez le msg à la méthode send, il reste sur ce thread ... – IAbstract

Répondre

1

Je recommande vraiment de ne pas le faire dans tous les cas. Les fonctions d'envoi peuvent envoyer moins que vous le dites pour diverses raisons très légitimes, et si un autre thread peut entrer et essayer d'envoyer aussi quelque chose, vous êtes en train de gâcher vos données.

Maintenant, vous pouvez certainement écrire sur une socket à partir de plusieurs threads, mais vous n'avez plus aucun contrôle sur ce qui se passe sur le fil à moins d'avoir un bon verrouillage au niveau de l'application.

envisager d'envoyer des données:

WSASend(sock,buf,buflen,&sent,0,0,0: 

le paramètre sent tiendra le pas. d'octets réellement envoyés - similaire à la valeur de retour de la fonction send(). Pour envoyer toutes les données au buf, vous devrez boucler un WSASend jusqu'à ce que toutes les données soient réellement envoyées.

Si, par exemple, le premier WSASend envoie tous les 4 derniers octets sauf un, un autre thread peut aller et envoyer quelque chose pendant que vous bouclez en arrière et essayez d'envoyer les 4 derniers octets.

Avec un bon verrouillage pour s'assurer que cela ne peut pas arriver, il ne devrait pas y avoir de problème d'envoi de plusieurs threads - je ne le ferais pas de toute façon juste pour le débogage.

+0

ok, mais votre exemple d'échec suppose une boucle while sur send. Ma question ne l'impliquait pas nécessairement. pouvez-vous donner un exemple similaire d'échec sans la boucle while? – jim

1

est-il possible d'avoir plusieurs threads envoyant sur le même socket?

Oui - bien que, selon la mise en œuvre, cela peut être plus ou moins visible. Tout d'abord, je vais préciser où je viens:

  1. C#/.Net 3.5
  2. System.Net.Sockets.Socket

La visibilité globale (ie de gestion nécessaire) du filetage et les maux de tête subis dépendront directement de la façon dont le socket est implémenté (de manière synchrone ou asynchrone). Si vous suivez la route synchrone, vous devrez gérer manuellement la connexion, l'envoi et la réception sur plusieurs threads. Je recommande fortement que cette implémentation soit évitée. Les efforts pour effectuer correctement et efficacement les méthodes synchrones dans un modèle threadé ne valent tout simplement pas les efforts comparables pour implémenter les méthodes asynchrones.

J'ai implémenté un serveur Tcp asynchrone en moins de temps qu'il n'en fallait pour implémenter la version synchrone à threads. Async est beaucoup plus facile à déboguer - et si vous êtes intéressé par Tcp (mon choix préféré) alors vous avez vraiment peu de soucis dans les messages perdus, les données manquantes, ou peu importe.

y aura-t-il un entrelacement des flux ou le bloc socket sur le premier thread (en supposant tcp)?

J'ai dû faire des recherches sur le interleaved flux (à partir du wiki) pour m'assurer que je comprenais exactement ce que vous demandiez. Pour mieux comprendre désentrelacement et messages mixtes, reportez-vous à ces liens sur le wiki:

  1. Real Time Messaging Protocol
  2. Transmission Control Protocol

Plus précisément, la puissance de Tcp est décrite dans la section suivante:

En raison de l'encombrement du réseau, de l'équilibrage de la charge du trafic ou d'autres comportements imprévisibles du réseau, IP pac les kets peuvent être perdus, dupliqués ou livrés en désordre. TCP détecte ces problèmes, demande la retransmission des paquets perdus, réorganise les paquets en panne, et contribue même à réduire l'encombrement du réseau pour réduire l'occurrence des autres problèmes . Une fois que le récepteur TCP a finalement réassemblé une copie parfaite des données transmises à l'origine, il transmet ce datagramme au programme d'application. Ainsi, TCP extrait la communication de l'application à partir des détails de réseau sous-jacents.

Cela signifie que les messages seront intercalées réorganisés dans leurs messages respectifs comme envoyé par l'expéditeur. On s'attend à ce que le thread soit impliqué dans le développement d'un mécanisme client/serveur Tcp basé sur les performances, que ce soit par le biais de méthodes asynchrones ou synchrones.

Pour empêcher le blocage d'un socket, vous pouvez définir sa propriété Blocking sur false. J'espère que cela vous donne de bonnes informations pour travailler avec. Heck, j'ai même appris un peu ...

+0

salut dboarman, merci pour la réponse. en entrelacant dans ce contexte, je voulais dire deux threads effectuant un envoi simultanément ... leurs paquets seraient-ils mélangés? J'ai édité ma question pour refléter cette clarification. – jim

Questions connexes