Điều khiển thông điệp dùng giao thức TCP thường gây ra khó khăn cho các lập trình viên nên .NET Framework cung cấp một số lớp để giảm gánh nặng lập trình. Một trong những lớp đó là NetworkStream, và hai lớp dùng để gởi và nhận text sử dụng giao thức TCP là StreamWriter và StreamReader.
Lớp NetworkStream
Lớp NetworkStream nằm trong namespace System.Net.Socket, lớp này có nhiều phương thức tạo lập để tạo một thể hiện của lớp NetworkStream nhưng phương thức tạo lập sau hay được dùng nhất:
Socket server = new Socket(AddressFamily.InterNetwork, SocketType.Stream, ProtocolType.Tcp); NetworkStream ns = new NetworkStream();
Phương thức Read() được dùng để đọc các khối dữ liệu từ NetworkStream.
Định dạng của phương thức này:
int Read(byte[] buffer, int offset, int size);
Phương thức này trả về một giá trị interger mô tả số byte thực sự đọc được từ NetworkStream và dặt dữ liệu đọc được vào buffer.
Phương thức Write() dùng để gởi các khối dữ liệu đi cũng có định dạng tương tự:
void Write(byte[] buffer, int offset, int size);
Sau đây sẽ là ví dụ tạo ra một đối tượng NetworkStream từ đối tượng Socket.
Khi đối tượng NetworkStream được tạo ra, đối tượng Socket sẽ không được tham chiếu đến nữa cho đến khi nó bị đóng lại vào cuối chương trình, tất cả các thông tin liên lạc với Server ở xa được thực hiện thông đối tượng NetworkStream:
Phương thức Flush() được dùng sau mỗi phương thức Write() để đảm bảo dữ liệu đặt vào NetworkStream sẽ lập tức được gởi đến hệ thống ở xa. Mặc dù đối tượng NetworkStream có thêm một số chức năng của Socket nhưng vẫn còn tồn tại vấn đề với biên thông điệp. Vấn đề này được giải quyết thông qua hai lớp hỗ trợ là StreamReader và StreamWriter.
Chương trình TCP Client NetworkStream
using System; using System.Net; using System.Net.Sockets; using System.Text; class NetworkStreamTcpClient { public static void Main() { byte[] data = new byte[1024]; string input, stringData; int recv; IPEndPoint ipep = new IPEndPoint(IPAddress.Parse("127.0.0.1"), 500); Socket server = new Socket(AddressFamily.InterNetwork, SocketType.Stream, ProtocolType.Tcp); try { server.Connect(ipep); } catch (SocketException e) { Console.WriteLine("Khong the ket noi den server"); Console.WriteLine(e.ToString()); return; NetworkStream ns = new NetworkStream(server); if (ns.CanRead) { recv = ns.Read(data, 0, data.Length); stringData = Encoding.ASCII.GetString(data, 0, recv); Console.WriteLine(stringData); } else { Console.WriteLine("Error: Can't read from this Socket"); ns.Close(); server.Close(); return; } while (true) { input = Console.ReadLine(); if (input == "exit") break; if (ns.CanWrite) { ns.Write(Encoding.ASCII.GetBytes(input), 0, input.Length); ns.Flush(); } recv = ns.Read(data, 0, data.Length); stringData = Encoding.ASCII.GetString(data, 0, recv); Console.WriteLine(stringData); } Console.WriteLine("Dang ngat ket noi voi server..."); ns.Close(); server.Shutdown(SocketShutdown.Both); server.Close(); } } }
Ta có thể kiểm tra chương trình này với chương trình TCP Server đơn giản tại đây .
Bài viết trên nhằm giới thiệu đến các bạn cách sử dụng lớp NetworkStream ở thư viện System.Net.Socket. Ngoài ra C# Stream với TCP còn dùng ở Lớp StreamReader và StreamWriter, vấn đề này sẽ được giới thiệu ở bài viết sau. Cảm ơn các bạn đã theo dõi, chúc các bạn thành công.