CodeBlanks Logo Icon CodeBlanks

TCP dinleyici

TcpListener ile istemci kabul eden döngü kurarsın.

Sohbet sunucusu: TCP dinleyici

Bu projede birden çok istemcinin bağlanıp mesajlaştığı bir sohbet sunucusu kuracağız. İlk adım bağlantı kabul etmek: TcpListener::bind bir adres dinler, accept bir istemci bağlanana kadar bekler ve bir TcpStream döndürür:

use std::net::TcpListener;

let dinleyici = TcpListener::bind("127.0.0.1:7878")?;
for baglanti in dinleyici.incoming() {
    let akis = baglanti?;
    println!("bağlandı: {}", akis.peer_addr()?);
}

Port olarak 0 verilirse işletim sistemi boş bir port seçer; local_addr() ile hangisi olduğu öğrenilir. Testler için kullanışlıdır.

Okumak ve yazmak

TcpStream hem Read hem Write uygular. Satır tabanlı bir protokolde okuma için BufReader::read_line, yazma için writeln! kullanılır:

use std::io::{BufRead, BufReader, Write};
use std::net::TcpStream;

let mut istemci = TcpStream::connect(adres)?;
writeln!(istemci, "merhaba")?;

let (akis, _) = dinleyici.accept()?;
let mut satir = String::new();
BufReader::new(akis).read_line(&mut satir)?;

Uygulama İlk bağlantı

127.0.0.1:0 adresini dinle ve local_addr() ile adresi al. Bir thread bu adrese bağlanıp merhaba satırını yazsın. Ana thread accept ile bağlantıyı alsın, satırı okusun ve alındı: merhaba yazdırsın.

Başlangıç kodu

main.rs
use std::io::{self, BufRead, BufReader, Write};
use std::net::{TcpListener, TcpStream};
use std::thread;

fn main() {
    // buraya yaz
}

Örnek çözüm

main.rs
use std::io::{self, BufRead, BufReader, Write};
use std::net::{TcpListener, TcpStream};
use std::thread;

fn main() -> io::Result<()> {
    let dinleyici = TcpListener::bind("127.0.0.1:0")?;
    let adres = dinleyici.local_addr()?;
    let istemci = thread::spawn(move || -> io::Result<()> {
        let mut akis = TcpStream::connect(adres)?;
        writeln!(akis, "merhaba")?;
        Ok(())
    });
    let (akis, _) = dinleyici.accept()?;
    let mut s = String::new();
    BufReader::new(akis).read_line(&mut s)?;
    println!("alındı: {}", s.trim());
    istemci.join().unwrap()?;
    Ok(())
}

Beklenen çıktı

alındı: merhaba

Soru ve cevaplar

Dersin sorularını cevaplarıyla birlikte inceleyebilirsin. Kendini denemek istersen dersi interaktif olarak çöz.

1 <code>incoming()</code> döngüsü ne zaman biter?

  • Hiçbir zaman; sunucu sürekli yeni bağlantı bekler Doğru cevap
  • İlk bağlantıdan sonra
  • Bağlantı kalmayınca
  • Bir saniye sonra

Açıklama: Belirli sayıda bağlantı için .take(n) kullanılabilir; testlerde bu, döngünün bitmesini sağlar.

2 Bağlantı kabul et

Soru
let (akis, adres) = dinleyici.____()?;
Cevap
let (akis, adres) = dinleyici.accept()?;

Açıklama: accept bir istemci bağlanana kadar bekler.

3 Fonksiyon ve görevi

Kavram Anlamı
TcpListener::bind Adres dinler
accept() Bağlantı bekler
TcpStream::connect Sunucuya bağlanır
local_addr() Gerçek port

İleri seviye bölümündeki tüm dersler