J'ai un système de communication basé sur TcpClient, et il fonctionne très bien, sauf quand il fait HTTPS à une adresse IP particulière. Ensuite, il commence à échouer.Comment faire HTTPS avec TcpClient comme le fait HttpWebRequest?
En utilisant un navigateur ou HttpWebRequest, je n'ai aucun problème à faire HTTPS à cette adresse IP.
J'ai créé un programme de test pour réduire mon problème à son essence de base, vous pouvez avoir un coup d'oeil ici si vous voulez: TestViaTcp
Ce programme de test fonctionne parfaitement pour HTTP de base à la même adresse IP , il produit toujours une réponse réussie à la demande. Je le mets en boucle, je le déclenche avec une pression sur une touche, il continuera à fonctionner toute la journée. Dès que je bascule le HTTPS, je reçois un motif récurrent. Ça marchera, et ça ne marchera pas, le succès sera suivi par l'échec suivi par le succès tout au long de la journée.
L'échec particulier, je continue à obtenir est celui-ci:
{"Authentication failed because the remote party has closed the transport stream."}
[System.IO.IOException]: {"Authentication failed because the remote party has closed the transport stream."}
Data: {System.Collections.ListDictionaryInternal}
HelpLink: null
InnerException: null
Message: "Authentication failed because the remote party has closed the transport stream."
Source: "System"
TargetSite: {Void StartReadFrame(Byte[], Int32, System.Net.AsyncProtocolRequest)}
Et voici la trace de la pile attachée à ce:
at System.Net.Security.SslState.StartReadFrame(Byte[] buffer, Int32 readBytes, AsyncProtocolRequest asyncRequest)
at System.Net.Security.SslState.StartReceiveBlob(Byte[] buffer, AsyncProtocolRequest asyncRequest)
at System.Net.Security.SslState.CheckCompletionBeforeNextReceive(ProtocolToken message, AsyncProtocolRequest asyncRequest)
at System.Net.Security.SslState.StartSendBlob(Byte[] incoming, Int32 count, AsyncProtocolRequest asyncRequest)
at System.Net.Security.SslState.ForceAuthentication(Boolean receiveFirst, Byte[] buffer, AsyncProtocolRequest asyncRequest)
at System.Net.Security.SslState.ProcessAuthentication(LazyAsyncResult lazyResult)
at System.Net.Security.SslStream.AuthenticateAsClient(String targetHost, X509CertificateCollection clientCertificates, SslProtocols enabledSslProtocols, Boolean checkCertificateRevocation)
at DeriveClassNameSpace.Services.Web.TcpMessaging.TestViaTcp(IPEndPoint endpoint, String auth, Boolean useSSL)
HttpWebRequest et le navigateur sont tous les deux (IIRC) en utilisant les bibliothèques Win32 pour gérer la communication de va-et-vient, alors que TcpClient est (AFAIK) en utilisant la classe .net Socket gérée, donc je suis sûr qu'il y a une grande différence entre eux. J'ai besoin de faire cela avec TcpClient, donc malheureusement je ne peux pas simplement "utiliser HttpWebRequest puisque je sais que je peux le faire fonctionner".
Le plus grand indice quant à ce que le problème est ici est probablement le modèle «fonctionne, ne fonctionne pas, ne fonctionne pas», qu'est-ce qui cause cela? Que puis-je faire pour éviter l'IOException que je reçois? Existe-t-il un moyen d'obtenir le comportement «fonctionne toujours» que je peux voir lorsque je fais le HTTPS avec HttpWebRequest?
Il devrait y avoir quelque chose que je peux faire avec TcpClient pour qu'il agisse et réagisse comme le fait HttpWebRequest, mais je n'y suis pas encore. Des idées?
Remarque: Le serveur avec lequel je communique est configurable pour savoir sur quel port il écoute et quel protocole il attend, mais il est par ailleurs totalement non modifiable. Notez également: J'ai lu que .net 3.5 avait ce problème particulier avec SslStream avant SP1, mais j'ai SP1 et mon programme est conçu pour cibler 3.5 donc je suppose que ce n'est pas un 'connu' bug 'Je cours ici.