Uwaga
Dostęp do tej strony wymaga autoryzacji. Może spróbować zalogować się lub zmienić katalogi.
Dostęp do tej strony wymaga autoryzacji. Możesz spróbować zmienić katalogi.
Zanim będzie można użyć gniazda do komunikowania się z urządzeniami zdalnymi, gniazdo musi zostać zainicjowane przy użyciu informacji o protokole i adresie sieciowym. Konstruktor klasy Socket ma parametry, które określają rodzinę adresów, typ gniazda i typ protokołu używany przez gniazdo do nawiązywania połączeń. Podczas łączenia gniazda klienta z gniazdem serwera klient użyje IPEndPoint
obiektu w celu określenia adresu sieciowego serwera.
Tworzenie punktu końcowego adresu IP
Podczas pracy z usługą System.Net.Socketsreprezentujesz punkt końcowy sieci jako IPEndPoint obiekt. Obiekt IPEndPoint
jest skonstruowany z numerem IPAddress i odpowiadającym mu numerem portu. Zanim będzie można zainicjować konwersację za pośrednictwem elementu , należy utworzyć potok danych między aplikacją Socketa zdalnym miejscem docelowym.
Protokół TCP/IP używa adresu sieciowego i numeru portu usługi, aby jednoznacznie zidentyfikować usługę. Adres sieciowy identyfikuje określone miejsce docelowe sieci; numer portu identyfikuje konkretną usługę na tym urządzeniu do nawiązania połączenia. Połączenie adresu sieciowego i portu usługi jest nazywane punktem końcowym, który jest reprezentowany na platformie .NET przez klasę EndPoint . Element potomny elementu jest definiowany dla każdej obsługiwanej EndPoint
rodziny adresów; dla rodziny adresów IP klasa to IPEndPoint.
Klasa Dns udostępnia usługi nazw domen dla aplikacji korzystających z usług internetowych TCP/IP. Metoda GetHostEntryAsync wysyła zapytanie do serwera DNS, aby zamapować przyjazną dla użytkownika nazwę domeny (na przykład "host.contoso.com") na numeryczny adres internetowy (na przykład 192.168.1.1
).
GetHostEntryAsync
Zwraca element Task<IPHostEntry>
, który w przypadku oczekiwania zawiera listę adresów i aliasów dla żądanej nazwy. W większości przypadków można użyć pierwszego adresu zwróconego w tablicy AddressList . Poniższy kod pobiera IPAddress adres IP serwera host.contoso.com
.
IPHostEntry ipHostInfo = await Dns.GetHostEntryAsync("host.contoso.com");
IPAddress ipAddress = ipHostInfo.AddressList[0];
Wskazówka
Do celów testowania ręcznego i debugowania zazwyczaj można użyć GetHostEntryAsync metody z wynikową nazwą hosta z Dns.GetHostName() wartości, aby rozpoznać nazwę hosta lokalnego na adres IP. Rozważmy następujący fragment kodu:
var hostName = Dns.GetHostName();
IPHostEntry localhost = await Dns.GetHostEntryAsync(hostName);
// This is the IP address of the local machine
IPAddress localIpAddress = localhost.AddressList[0];
Urząd IANA (Internet Assigned Numbers Authority) definiuje numery portów dla typowych usług. Aby uzyskać więcej informacji, zobacz IANA: Service Name and Transport Protocol Port Number Registry (IANA: nazwa usługi i rejestr numerów portów protokołu transportu). Inne usługi mogą mieć zarejestrowane numery portów w zakresie od 1024 do 65 535. Poniższy kod łączy adres IP z host.contoso.com
numerem portu w celu utworzenia zdalnego punktu końcowego dla połączenia.
IPEndPoint ipEndPoint = new(ipAddress, 11_000);
Po określeniu adresu urządzenia zdalnego i wybraniu portu do użycia dla połączenia aplikacja może nawiązać połączenie z urządzeniem zdalnym.
Tworzenie Socket
klienta
Po utworzeniu endPoint
obiektu utwórz gniazdo klienta, aby nawiązać połączenie z serwerem. Po nawiązaniu połączenia gniazdo może wysyłać i odbierać dane z połączenia gniazda serwera.
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);
Poprzedni kod języka C#:
Tworzy wystąpienie nowego obiektu
Socket
z daną rodziną adresów instancjiendPoint
, SocketType.Stream oraz ProtocolType.Tcp.Wywołuje metodę Socket.ConnectAsync z wystąpieniem
endPoint
jako argumentem.W
while
pętli:- Koduje i wysyła komunikat do serwera przy użyciu polecenia Socket.SendAsync.
- Zapisuje wysłaną wiadomość do konsoli programu .
- Inicjuje bufor do odbierania danych z serwera przy użyciu polecenia Socket.ReceiveAsync.
-
response
Gdy element jest potwierdzeniem, jest zapisywany w konsoli, a pętla jest zamykana.
Na koniec gniazdo wywołuje
client
podane Socket.Shutdown i SocketShutdown.Both, co zamyka zarówno operacje wysyłania, jak i odbierania.
Tworzenie Socket
serwera
Aby utworzyć gniazdo serwera, obiekt może nasłuchiwać połączeń przychodzących na dowolnym adresie IP, endPoint
ale należy określić numer portu. Po utworzeniu gniazda serwer może akceptować połączenia przychodzące i komunikować się z klientami.
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|>"
}
Poprzedni kod języka C#:
Tworzy wystąpienie nowego obiektu
Socket
z daną rodziną adresów instancjiendPoint
, SocketType.Stream oraz ProtocolType.Tcp.listener
wywołuje metodę Socket.Bind z wystąpieniemendPoint
jako argument, aby skojarzyć gniazdo z adresem sieciowym.Metoda Socket.Listen() jest wywoływana w celu nasłuchiwania połączeń przychodzących.
listener
wywołuje metodę Socket.AcceptAsync w celu akceptowania połączenia przychodzącego na gnieździehandler
.W
while
pętli:- Wywołuje Socket.ReceiveAsync do odbierania danych od klienta.
- Po odebraniu danych są dekodowane i zapisywane w konsoli.
-
response
Jeśli komunikat zakończy się ciągiem<|EOM|>
, potwierdzenie zostanie wysłane do klienta przy użyciu polecenia Socket.SendAsync.
Uruchamianie przykładowego klienta i serwera
Najpierw uruchom aplikację serwera, a następnie uruchom aplikację kliencka.
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...
Aplikacja kliencka wyśle komunikat na serwer, a serwer odpowie potwierdzeniem.
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...