Voici un problème vraiment étrange: Apparemment, la séquence spécifique d'octets qui se traduit par ASCII "PUttttt"
, si elle est envoyée via un socket TCP ne le rend pas du tout au client.Sockets cassés dans .NET?
J'ai inclus l'exemple de code utilisé pour illustrer le problème ci-dessous dans l'espoir que quelqu'un puisse avoir une idée de la raison pour laquelle cela se produit. Les applications serveur et client ont été intentionnellement réduites à de simples versions synchrones de console pour faciliter le dépannage.
L'aspect clé du problème est la donnée qui va dans le tampon d'envoi (la chaîne "PUttttt").
Le serveur:
using System;
using System.Net.Sockets;
using System.Net;
namespace ConsoleServer
{
private static Socket mServer;
private static byte[] fileBytes;
private static int sent_total;
static void Main(string[] args)
{
string hostName = "localhost"; //Dns.GetHostName();
IPHostEntry ipHostInfo = Dns.GetHostEntry(hostName);
IPAddress iaddr = null;
for(int k = 0; k < ipHostInfo.AddressList.Length; k++)
if (ipHostInfo.AddressList[k].AddressFamily == AddressFamily.InterNetwork)
{
iaddr = ipHostInfo.AddressList[k];
break;
}
if (iaddr == null)
{
Console.WriteLine("Can not bind to any interface.. Server can not start");
Console.ReadKey();
return;
}
mServer = new Socket(iaddr.AddressFamily, SocketType.Stream, ProtocolType.Tcp);
mServer.Bind(new IPEndPoint(iaddr, 8000));
Console.WriteLine("Server: Bound to " + hostName + " (" + iaddr.ToString() + "):8000");
mServer.Listen(1);
Console.WriteLine("Server: Started. Awaiting connection.");
Socket handler = mServer.Accept();
handler.LingerState = new LingerOption(true, 5);
Console.WriteLine("Server: A Client connected\r\nServer: sending data");
string str = @"PUttttt";
fileBytes = System.Text.ASCIIEncoding.ASCII.GetBytes(str);
SocketError errCode = SocketError.Success;
int sent = handler.Send(fileBytes, 0, fileBytes.Length, SocketFlags.None, out errCode);
sent_total += sent;
Console.WriteLine("Server: Done sending. " + sent_total + " bytes (" + errCode.ToString() + ")");
handler.Close();
Console.WriteLine("Server: CLient Disconnected");
Console.ReadKey();
}
}
}
Le client:
using System;
using System.Net.Sockets;
using System.Net;
namespace ConsoleClient
{
class Program
{
private static int BUFFER_SIZE = 1024 * 1024;
private static string SERVER_ADDR = "localhost"; //Dns.GetHostName();
private static int SERVER_PORT = 8000;
static void Main(string[] args)
{
Console.WriteLine("Client: connecting to " + SERVER_ADDR + " server");
Socket socket = new Socket(AddressFamily.InterNetwork, SocketType.Stream, ProtocolType.Tcp);
socket.ReceiveTimeout = 30000;
socket.ReceiveBufferSize = BUFFER_SIZE;
IPHostEntry ipHostInfo = Dns.GetHostEntry(SERVER_ADDR);
IPAddress ipAddress = null;
for (int k = 0; k < ipHostInfo.AddressList.Length; k++)
if (ipHostInfo.AddressList[k].AddressFamily == AddressFamily.InterNetwork)
{
ipAddress = ipHostInfo.AddressList[k];
break;
}
socket.Connect(new IPEndPoint(ipAddress, SERVER_PORT));
Console.WriteLine("Client: connected");
byte[] buffer = new byte[BUFFER_SIZE];
int total = 0;
int read = socket.Receive(buffer, buffer.Length, SocketFlags.None);
total += read;
Console.WriteLine("Client: read " + read + " bytes. " + total + " total");
while (read > 0)
{
try
{
read = socket.Receive(buffer, buffer.Length, SocketFlags.None);
total += read;
Console.WriteLine("Client: read " + read + " bytes. " + total + " total: ");
}
catch (Exception se)
{
Console.WriteLine(se.ToString());
break;
}
}
Console.WriteLine("Client: received " + total + " bytes");
socket.Shutdown(SocketShutdown.Both);
socket.Close();
Console.WriteLine("Connection Closed.");
Console.ReadKey();
}
}
}
J'ai compilé cette aide de Visual Studio 2010 et le .NET 4 Client Profile mais je pense qu'il est cassé dans d'autres versions de .NET.
est ici la sortie du serveur:
Server: Bound to localhost (127.0.0.1):8000
Server: Started. Awaiting connection.
Server: A Client connected
Server: sending data
Server: Done sending. 7 bytes (Success)
Server: CLient Disconnected
Et ceci est la sortie du client
Client: connecting to localhost server
Client: connected
Client: read 0 bytes. 0 total
Client: received 0 bytes
Connection Closed.
Notez la différence entre ce qui est envoyé à partir du serveur et ce qui est reçu par le client . En outre, si la ligne qui ferme le socket sur le serveur est mise en commentaire, le client se bloque en attente de réception des données.
Et ce code fonctionne pour tout sauf "PUttttt"? Cela semble être un bug vraiment improbable ... il doit y avoir quelque chose d'autre qui se passe –
@Thomas, as-tu essayé de compiler et d'exécuter ce code? Ce qui est intéressant, c'est que le code fonctionne bien sur une machine mais j'en ai deux autres sur lesquels ça ne marche pas. Même les commentaires aussi simples que cela serait utile –
Votre code fonctionne très bien sur ma machine (Vista, VS2008, .NET 3.5) –