Megosztás a következőn keresztül:


Adatok TCP-en keresztüli küldése és fogadása a Szoftvercsatornák használatával

Mielőtt szoftvercsatornával kommunikálhat a távoli eszközökkel, a szoftvercsatornát inicializálni kell protokoll- és hálózati címadatokkal. Az osztály konstruktorának Socket paraméterei megadják a címcsaládot, a szoftvercsatorna típusát és a protokoll típusát, amelyet a szoftvercsatorna használ a kapcsolatok létrehozásához. Amikor egy ügyfélcsatornát egy kiszolgálócsatornához csatlakoztat, az ügyfél egy IPEndPoint objektummal adja meg a kiszolgáló hálózati címét.

IP-végpont létrehozása

A munka System.Net.Socketssorán egy hálózati végpontot jelöl objektumként IPEndPoint . A IPEndPoint felépítése egy IPAddress és annak megfelelő portszámmal történik. Mielőtt beszélgetést kezdeményezhet egy Socketalkalmazáson keresztül, hozzon létre egy adatcsatornát az alkalmazás és a távoli cél között.

A TCP/IP egy hálózati címet és egy szolgáltatásportszámot használ a szolgáltatás egyedi azonosításához. A hálózati cím azonosít egy adott hálózati célt; a portszám azonosítja az adott szolgáltatást azon az eszközön, amelyhez csatlakozni szeretne. A hálózati cím és a szolgáltatásport kombinációját végpontnak nevezzük, amelyet a .NET-ben az EndPoint osztály jelöl. A program minden támogatott címcsaládhoz meghatároz egy leszármazottat EndPoint ; az IP-címcsalád esetében az osztály a IPEndPoint.

Az Dns osztály tartománynév-szolgáltatásokat biztosít a TCP/IP internetszolgáltatásokat használó alkalmazások számára. A GetHostEntryAsync metódus lekérdez egy DNS-kiszolgálót egy felhasználóbarát tartománynév (például "host.contoso.com") numerikus internetcímre (például 192.168.1.1). GetHostEntryAsync visszaad egy Task<IPHostEntry> olyan értéket, amely a várt állapotban tartalmazza a kért név címeinek és aliasainak listáját. A legtöbb esetben használhatja a tömbben AddressList visszaadott első címet. A következő kód a IPAddress kiszolgáló host.contoso.comIP-címét tartalmazza.

IPHostEntry ipHostInfo = await Dns.GetHostEntryAsync("host.contoso.com");
IPAddress ipAddress = ipHostInfo.AddressList[0];

Tipp.

Manuális tesztelési és hibakeresési célokra általában a GetHostEntryAsync metódust használhatja az eredményül kapott gazdagépnévvel az Dns.GetHostName() értékből a localhost név IP-címre való feloldásához. Vegye figyelembe a következő kódrészletet:

var hostName = Dns.GetHostName();
IPHostEntry localhost = await Dns.GetHostEntryAsync(hostName);
// This is the IP address of the local machine
IPAddress localIpAddress = localhost.AddressList[0];

Az Internet Assigned Numbers Authority (IANA) a gyakori szolgáltatások portszámait határozza meg. További információ : IANA: Service Name and Transport Protocol Port Number Registry). Más szolgáltatások 1024 és 65 535 közötti tartományba tartozó regisztrált portszámokkal rendelkezhetnek. Az alábbi kód egy portszámmal egyesíti az IP-címet host.contoso.com egy távoli végpont létrehozásához egy kapcsolathoz.

IPEndPoint ipEndPoint = new(ipAddress, 11_000);

A távoli eszköz címének meghatározása és a kapcsolathoz használandó port kiválasztása után az alkalmazás kapcsolatot létesíthet a távoli eszközzel.

Socket Ügyfél létrehozása

endPoint Az objektum létrehozásával hozzon létre egy ügyfélcsatornát a kiszolgálóhoz való csatlakozáshoz. A szoftvercsatorna csatlakoztatása után adatokat küldhet és fogadhat a kiszolgáló szoftvercsatorna-kapcsolatáról.

using Socket client = new(
    ipEndPoint.AddressFamily, 
    SocketType.Stream, 
    ProtocolType.Tcp);

await client.ConnectAsync(ipEndPoint);
while (true)
{
    // Send message.
    var message = "Hi friends 👋!<|EOM|>";
    var messageBytes = Encoding.UTF8.GetBytes(message);
    _ = await client.SendAsync(messageBytes, SocketFlags.None);
    Console.WriteLine($"Socket client sent message: \"{message}\"");

    // Receive ack.
    var buffer = new byte[1_024];
    var received = await client.ReceiveAsync(buffer, SocketFlags.None);
    var response = Encoding.UTF8.GetString(buffer, 0, received);
    if (response == "<|ACK|>")
    {
        Console.WriteLine(
            $"Socket client received acknowledgment: \"{response}\"");
        break;
    }
    // Sample output:
    //     Socket client sent message: "Hi friends 👋!<|EOM|>"
    //     Socket client received acknowledgment: "<|ACK|>"
}

client.Shutdown(SocketShutdown.Both);

Az előző C# kód:

  • Létrehoz egy új Socket objektumot egy adott endPoint példány címcsaládjával, a SocketType.Stream.ProtocolType.Tcp

  • Argumentumként meghívja a Socket.ConnectAsync metódust a endPoint példánysal.

  • Ciklusban while :

    • Kódolja és elküldi az üzenetet a kiszolgálónak a használatával Socket.SendAsync.
    • Az elküldött üzenetet a konzolra írja.
    • Inicializál egy puffert, hogy adatokat fogadjon a kiszolgálóról a következő használatával Socket.ReceiveAsync: .
    • Ha a response rendszer nyugtát ad, a rendszer a konzolra írja, és a hurok ki lesz lépve.
  • Végül pedig a client megadott SocketShutdown.Bothszoftvercsatornás hívásokSocket.Shutdown, amelyek a küldési és fogadási műveleteket is leállítják.

Kiszolgáló létrehozása Socket

A kiszolgálócsatorna létrehozásához az endPoint objektum bármely IP-címen figyelheti a bejövő kapcsolatokat, de meg kell adni a portszámot. A szoftvercsatorna létrehozása után a kiszolgáló fogadni tudja a bejövő kapcsolatokat, és kommunikálhat az ügyfelekkel.

using Socket listener = new(
    ipEndPoint.AddressFamily,
    SocketType.Stream,
    ProtocolType.Tcp);

listener.Bind(ipEndPoint);
listener.Listen(100);

var handler = await listener.AcceptAsync();
while (true)
{
    // Receive message.
    var buffer = new byte[1_024];
    var received = await handler.ReceiveAsync(buffer, SocketFlags.None);
    var response = Encoding.UTF8.GetString(buffer, 0, received);
    
    var eom = "<|EOM|>";
    if (response.IndexOf(eom) > -1 /* is end of message */)
    {
        Console.WriteLine(
            $"Socket server received message: \"{response.Replace(eom, "")}\"");

        var ackMessage = "<|ACK|>";
        var echoBytes = Encoding.UTF8.GetBytes(ackMessage);
        await handler.SendAsync(echoBytes, 0);
        Console.WriteLine(
            $"Socket server sent acknowledgment: \"{ackMessage}\"");

        break;
    }
    // Sample output:
    //    Socket server received message: "Hi friends 👋!"
    //    Socket server sent acknowledgment: "<|ACK|>"
}

Az előző C# kód:

  • Létrehoz egy új Socket objektumot egy adott endPoint példány címcsaládjával, a SocketType.Stream.ProtocolType.Tcp

  • A listener metódus argumentumként meghívja a Socket.Bind metódust a endPoint példányhoz, hogy a szoftvercsatornát a hálózati címhez rendelje.

  • A Socket.Listen() metódus a bejövő kapcsolatok figyelésére van meghívva.

  • A listener metódus meghívja a Socket.AcceptAsync metódust, hogy fogadjon el egy bejövő kapcsolatot a handler szoftvercsatornán.

  • Ciklusban while :

    • Az ügyféltől érkező adatok fogadására irányuló hívások Socket.ReceiveAsync .
    • Az adatok fogadásakor az adatok dekódolva lesznek, és a konzolra lesznek írva.
    • Ha az response üzenet véget ér <|EOM|>, a rendszer nyugtát küld az ügyfélnek a Socket.SendAsynckövetkező használatával: .

A mintaügyfél és a kiszolgáló futtatása

Először indítsa el a kiszolgálóalkalmazást, majd indítsa el az ügyfélalkalmazást.

dotnet run --project socket-server
Socket server starting...
Found: 172.23.64.1 available on port 9000.
Socket server received message: "Hi friends 👋!"
Socket server sent acknowledgment: "<|ACK|>"
Press ENTER to continue...

Az ügyfélalkalmazás üzenetet küld a kiszolgálónak, és a kiszolgáló nyugtával válaszol.

dotnet run --project socket-client
Socket client starting...
Found: 172.23.64.1 available on port 9000.
Socket client sent message: "Hi friends 👋!<|EOM|>"
Socket client received acknowledgment: "<|ACK|>"
Press ENTER to continue...

Lásd még