C# Networking (TcpClient, HttpClient, REST API Çağrıları)
C#’ta networking konularını öğrenin. TcpClient, HttpClient ve REST API çağrıları ile veri iletişimi örneklerle anlatılıyor.
Modern uygulamalarda ağ iletişimi (networking) büyük bir rol oynar.
C#’ta hem düşük seviyeli TCP soketleri ile hem de yüksek seviyeli HTTP/REST API çağrılarıyla iletişim kurulabilir.
.NET, bu işlemler için güçlü sınıflar sunar: TcpClient, TcpListener ve HttpClient.
Bu makalede temel ağ programlama örneklerinden REST API çağrılarına kadar adım adım inceleyeceğiz.
1. TCP Nedir?
TCP (Transmission Control Protocol), bağlantı tabanlı ve güvenilir bir iletişim protokolüdür.
Veri paketleri sıralı olarak iletilir, hatalı paketler yeniden gönderilir.
TCP istemci–sunucu modelinde çalışır: bir taraf dinler (TcpListener), diğer taraf bağlanır (TcpClient).
2. TcpListener ile Basit Bir Sunucu
Aşağıdaki örnekte 5000 portundan gelen bağlantıları dinleyen bir TCP sunucusu gösterilmektedir.
using System;
using System.IO;
using System.Net;
using System.Net.Sockets;
using System.Text;
using System.Threading.Tasks;
class TcpServer
{
public static async Task StartAsync()
{
var listener = new TcpListener(IPAddress.Loopback, 5000);
listener.Start();
Console.WriteLine("Sunucu başlatıldı. 5000 portu dinleniyor...");
while (true)
{
using TcpClient client = await listener.AcceptTcpClientAsync();
Console.WriteLine("Yeni istemci bağlandı!");
using var stream = client.GetStream();
using var reader = new StreamReader(stream, Encoding.UTF8);
using var writer = new StreamWriter(stream, Encoding.UTF8) { AutoFlush = true };
string? message = await reader.ReadLineAsync();
Console.WriteLine($"İstemciden gelen: {message}");
await writer.WriteLineAsync($"Sunucudan yanıt: {message?.ToUpper()}");
}
}
static async Task Main() => await StartAsync();
}
Sunucu her yeni bağlantı aldığında mesajı okur, büyük harfe çevirip geri gönderir.
IPAddress.Loopback sadece yerel makineyi temsil eder.
3. TcpClient ile İstemci Bağlantısı
İstemci tarafında TcpClient kullanarak sunucuya bağlanabiliriz:
using System;
using System.IO;
using System.Net.Sockets;
using System.Text;
using System.Threading.Tasks;
class TcpClientApp
{
static async Task Main()
{
using var client = new TcpClient();
await client.ConnectAsync("127.0.0.1", 5000);
using var stream = client.GetStream();
using var writer = new StreamWriter(stream, Encoding.UTF8) { AutoFlush = true };
using var reader = new StreamReader(stream, Encoding.UTF8);
Console.Write("Mesaj: ");
string message = Console.ReadLine()!;
await writer.WriteLineAsync(message);
string response = await reader.ReadLineAsync() ?? "";
Console.WriteLine($"Sunucudan gelen: {response}");
}
}
Sunucuyu çalıştırdıktan sonra bu istemciyi başlatın. Gönderdiğiniz mesaj büyük harfle geri dönecektir.
4. HttpClient ile Web ve REST API Çağrıları
Günümüzde ağ iletişiminin en yaygın biçimi HTTP tabanlı REST servisleridir.
.NET’te HttpClient sınıfı bu işlemler için kullanılır.
Asenkron çalışır, yeniden kullanılabilir ve JSON tabanlı veri alışverişi için idealdir.
using System;
using System.Net.Http;
using System.Text.Json;
using System.Threading.Tasks;
class HttpClientExample
{
static readonly HttpClient http = new HttpClient();
static async Task Main()
{
var url = "https://jsonplaceholder.typicode.com/posts/1";
Console.WriteLine($"GET {url}");
var response = await http.GetAsync(url);
string json = await response.Content.ReadAsStringAsync();
var post = JsonSerializer.Deserialize<Post>(json);
Console.WriteLine($"Başlık: {post?.Title}");
}
public class Post
{
public int Id { get; set; }
public string? Title { get; set; }
public string? Body { get; set; }
}
}
Bu örnek, bir REST API'den JSON veri çekip C# sınıfına (Post) dönüştürür. JsonSerializer .NET’in yerleşik JSON desteğini kullanır.
5. POST İsteği Gönderme
HttpClient ile POST isteği gönderirken JSON içeriği manuel olarak oluşturabilir veya serileştirme kullanabilirsiniz.
using System.Net.Http;
using System.Text;
using System.Text.Json;
var http = new HttpClient();
var newPost = new
{
title = "Yeni Gönderi",
body = "Merhaba dünya!",
userId = 1
};
var json = JsonSerializer.Serialize(newPost);
var content = new StringContent(json, Encoding.UTF8, "application/json");
var response = await http.PostAsync("https://jsonplaceholder.typicode.com/posts", content);
Console.WriteLine($"Durum: {response.StatusCode}");
string result = await response.Content.ReadAsStringAsync();
Console.WriteLine($"Yanıt: {result}");
Bu örnek, REST API’ye veri göndermenin temel yoludur. Gerçek uygulamalarda async/await kalıbı kullanmak önemlidir.
6. HttpClient Yaşam Döngüsü (Best Practice)
HttpClient nesnesini her istek için yeniden oluşturmak kaynak tüketimine yol açar. Doğru yaklaşım, tek bir örnek (singleton) olarak kullanmaktır:
// Program.cs
builder.Services.AddHttpClient<IMyApiService, MyApiService>();
// Service
public class MyApiService : IMyApiService
{
private readonly HttpClient _http;
public MyApiService(HttpClient http)
{
_http = http;
_http.BaseAddress = new Uri("https://api.example.com/");
}
public async Task<User?> GetUserAsync(int id)
{
return await _http.GetFromJsonAsync<User>($"users/{id}");
}
}
ASP.NET Core’daki HttpClientFactory, bağlantı havuzlamasını (connection pooling) otomatik olarak yönetir.
7. Hata Yönetimi ve Timeout Ayarları
HTTP çağrılarında zaman aşımı, hata ve beklenmeyen durumlar için istisna yönetimi eklenmelidir.
var http = new HttpClient { Timeout = TimeSpan.FromSeconds(5) };
try
{
var response = await http.GetAsync("https://api.github.com/repos/dotnet/runtime");
response.EnsureSuccessStatusCode(); // 200–299 dışında hata fırlatır
string content = await response.Content.ReadAsStringAsync();
Console.WriteLine("Başarılı istek: " + content.Length + " byte");
}
catch (HttpRequestException ex)
{
Console.WriteLine($"HTTP hatası: {ex.Message}");
}
catch (TaskCanceledException)
{
Console.WriteLine("Zaman aşımı!");
}
8. SSL, Header ve Token Kullanımı
Çoğu modern API kimlik doğrulama için Authorization header’ı kullanır.
Header ve özel ayarları kolayca ekleyebilirsiniz:
var http = new HttpClient();
http.DefaultRequestHeaders.Add("Authorization", "Bearer <token>");
http.DefaultRequestHeaders.Add("User-Agent", "MyApp/1.0");
var res = await http.GetAsync("https://api.github.com/user");
Console.WriteLine(res.StatusCode);
HTTPS bağlantıları varsayılan olarak güvenlidir. Geliştirme ortamında (örneğin self-signed sertifika) özel handler ayarları yapılabilir.
9. Asenkron Akış ile Büyük Veriler
Büyük dosya veya veri akışlarında Stream üzerinden doğrudan okuma yapılabilir:
using var http = new HttpClient();
using var response = await http.GetAsync("https://example.com/bigfile.zip", HttpCompletionOption.ResponseHeadersRead);
await using var stream = await response.Content.ReadAsStreamAsync();
using var file = File.Create("indirilen.zip");
await stream.CopyToAsync(file);
Console.WriteLine("Dosya indirildi.");
Bu yöntem belleği verimli kullanır, dosya tamamen RAM’e yüklenmez.
10. Örnek: REST API Tüketimi (WeatherService)
Aşağıdaki örnek, bir hava durumu API’sinden veri çekip modele dönüştürür.
public class WeatherInfo
{
public string? City { get; set; }
public float Temperature { get; set; }
public string? Condition { get; set; }
}
public class WeatherService
{
private readonly HttpClient _http;
public WeatherService(HttpClient http)
{
_http = http;
_http.BaseAddress = new Uri("https://api.weatherapi.com/v1/");
}
public async Task<WeatherInfo?> GetAsync(string city)
{
var key = "<your-api-key>";
string url = $"current.json?key={key}&q={city}&aqi=no";
var res = await _http.GetAsync(url);
res.EnsureSuccessStatusCode();
using var s = await res.Content.ReadAsStreamAsync();
using var doc = await JsonDocument.ParseAsync(s);
return new WeatherInfo
{
City = city,
Temperature = doc.RootElement.GetProperty("current").GetProperty("temp_c").GetSingle(),
Condition = doc.RootElement.GetProperty("current").GetProperty("condition").GetProperty("text").GetString()
};
}
}
Bu yapı, Dependency Injection destekli HttpClientFactory ile Clean Architecture yapısına uyumludur.
11. Performans ve En İyi Uygulamalar
- HttpClient’i yeniden kullanın (tekil instance veya
IHttpClientFactory). - Timeout ve retry politikalarını Polly kütüphanesiyle yönetin.
- Asenkron işlemlerde
ConfigureAwait(false)kullanarak deadlock riskini azaltın. - TcpClient kullanıyorsanız
usingveawaitkombinasyonuyla kaynakları doğru kapatın. - Network IO işlemlerinde exception handling ve loglama her zaman eklenmelidir.
TL;DR
- TcpClient/TcpListener: Düşük seviyeli bağlantı tabanlı TCP iletişimi sağlar.
- HttpClient: REST API’lerle iletişim için yüksek seviyeli istemcidir.
- GetAsync, PostAsync: HTTP istekleri gönderir; JSON dönüşümleri
JsonSerializerile yapılır. - HttpClientFactory: Tekil örnek yönetimi ve performans için önerilir.
- Asenkron işlemler:
awaitkullanın,Timeoutve hata yönetimini unutmayın.
İlişkili Makaleler
C# Asenkron Programlama Temelleri (async/await)
C#’ta async ve await kullanımını öğrenin. Asenkron işlemler, Task yapısı ve performanslı uygulama akışları örneklerle anlatılıyor.
C# için Visual Studio / VS Code İpuçları
C# geliştiricileri için Visual Studio ve VS Code ipuçlarını öğrenin. Verimlilik artıran kısayollar ve geliştirme teknikleri.
C# Metotlar ve Parametre Kullanımı
C#’ta metot tanımlama ve parametre kullanımını öğrenin. Değer ve referans parametreleri, varsayılan parametreler ve örneklerle.