Bagikan melalui


Menggunakan Soket untuk mengirim dan menerima data melalui TCP

Sebelum Anda dapat menggunakan soket untuk berkomunikasi dengan perangkat jarak jauh, soket harus diinisialisasi dengan protokol dan informasi alamat jaringan. Konstruktor untuk Socket kelas memiliki parameter yang menentukan keluarga alamat, jenis soket, dan jenis protokol yang digunakan soket untuk membuat koneksi. Saat menyambungkan soket klien ke soket server, klien menggunakan IPEndPoint objek untuk menentukan alamat jaringan server.

Membuat titik akhir IP

Saat bekerja dengan System.Net.Sockets, Anda mewakili titik akhir jaringan sebagai IPEndPoint objek. IPEndPoint dibangun menggunakan IPAddress dengan nomor port yang sesuai. Sebelum dapat memulai percakapan melalui Socket, Anda membuat pipa data antara aplikasi dan tujuan jarak jauh.

TCP/IP menggunakan alamat jaringan dan nomor port layanan untuk mengidentifikasi layanan secara unik. Alamat jaringan mengidentifikasi tujuan jaringan tertentu; nomor port mengidentifikasi layanan tertentu pada perangkat tersebut untuk disambungkan. Kombinasi alamat jaringan dan port layanan disebut titik akhir, yang diwakili dalam .NET oleh EndPoint kelas . Keturunan EndPoint didefinisikan untuk setiap keluarga alamat yang didukung; untuk keluarga alamat IP, kelasnya adalah IPEndPoint.

Kelas ini Dns menyediakan layanan nama domain ke aplikasi yang menggunakan layanan internet TCP/IP. Metode ini GetHostEntryAsync meminta server DNS untuk memetakan nama domain yang mudah digunakan (seperti "host.contoso.com") ke alamat Internet numerik (seperti 192.168.1.1). GetHostEntryAsync mengembalikan sebuah Task<IPHostEntry> yang berisi daftar alamat dan alias untuk nama yang diminta ketika dinanti. Dalam kebanyakan kasus, Anda dapat menggunakan alamat pertama yang dikembalikan dalam AddressList array. Kode berikut mendapatkan IPAddress yang berisi alamat IP untuk server host.contoso.com.

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

Petunjuk / Saran

Untuk tujuan pengujian dan penelusuran kesalahan manual, Anda biasanya dapat menggunakan metode GetHostEntryAsync dengan nama host yang dihasilkan dari nilai Dns.GetHostName() untuk mengonversi nama localhost ke alamat IP. Perhatikan cuplikan kode berikut:

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

Internet Assigned Numbers Authority (IANA) menentukan nomor port untuk layanan umum. Untuk informasi selengkapnya, lihat IANA: Nama Layanan dan Registri Nomor Port Protokol Transportasi). Layanan lain dapat memiliki nomor port terdaftar dalam rentang 1.024 hingga 65.535. Kode berikut menggabungkan alamat IP untuk host.contoso.com dengan nomor port untuk membuat titik akhir jarak jauh untuk koneksi.

IPEndPoint ipEndPoint = new(ipAddress, 11_000);

Setelah menentukan alamat perangkat jarak jauh dan memilih port yang akan digunakan untuk koneksi, aplikasi dapat membuat koneksi dengan perangkat jarak jauh.

Membuat Socket klien

Dengan objek yang endPoint dibuat, buat soket klien untuk menyambungkan ke server. Setelah soket tersambung, soket dapat mengirim dan menerima data dari koneksi soket server.

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);

Kode C# sebelumnya:

  • Membuat instans objek baru Socket dengan keluarga alamat instans tertentu endPoint , SocketType.Stream, dan ProtocolType.Tcp.

  • Memanggil metode Socket.ConnectAsync dengan menjadikan instans endPoint sebagai argumen.

  • Dalam sebuah perulangan while :

    • Mengodekan dan mengirim pesan ke server menggunakan Socket.SendAsync.
    • Menulis pesan terkirim ke konsol.
    • Menginisialisasi buffer untuk menerima data dari server menggunakan Socket.ReceiveAsync.
    • Ketika response adalah pengakuan, itu dicetak ke konsol dan perulangan dihentikan.
  • Terakhir, soket memanggil client yang diberikan Socket.Shutdown, yang mematikan operasi kirim dan terima.

Buat server Socket

Untuk membuat soket server, endPoint objek dapat mendengarkan koneksi masuk pada alamat IP apa pun tetapi nomor port harus ditentukan. Setelah soket dibuat, server dapat menerima koneksi masuk dan berkomunikasi dengan klien.

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|>"
}

Kode C# sebelumnya:

  • Membuat instans objek baru Socket dengan keluarga alamat instans tertentu endPoint , SocketType.Stream, dan ProtocolType.Tcp.

  • Metode listener dipanggil dengan instans Socket.Bind sebagai argumen untuk mengaitkan soket dengan alamat jaringan.

  • Metode Socket.Listen() ini dipanggil untuk mendengarkan koneksi masuk.

  • listener memanggil metode Socket.AcceptAsync untuk menerima koneksi masuk pada soket handler.

  • Dalam sebuah perulangan while :

    • Memanggil Socket.ReceiveAsync untuk menerima data dari klien.
    • Saat data diterima, data akan didekode dan ditulis ke konsol.
    • response Jika pesan berakhir dengan <|EOM|>, pengakuan dikirim ke klien menggunakan Socket.SendAsync.

Jalankan klien sampel dan server

Mulai aplikasi server terlebih dahulu, lalu mulai aplikasi klien.

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...

Aplikasi klien mengirim pesan ke server, dan server akan merespons dengan pengakuan.

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...

Lihat juga