Thực hành: Lập trình socket Tcp cơ bản (+video) | Tự học ICT

Tương tự như so với socket Udp, tất cả chúng ta cũng khởi đầu tiếp xúc với socket Tcp trải qua thực thi một bài thực hành thực tế. Bài thực hành thực tế này cũng có chung nhu yếu với bài thực hành thực tế đã triển khai so với socket Udp : thiết kế xây dựng một bộ ứng dụng theo quy mô client / server được cho phép đổi khác một chuỗi ký tự người dùng nhập thành dạng chữ in hoa .Sơ đồ flowchart của bài toán này như sau :Sơ đồ flowchart các bước khi lập trình với Tcp socketSơ đồ flowchart các bước khi lập trình với Tcp socket

Bước 1. Tạo một
Solution trống đặt tên là TcpSocket

Bước 2. Xây dựng
lần lượt hai project thuộc kiểu Console App trong solution trên với tên gọi lần
lượt là Server và Client.

Bước 3. Thiết lập để có thể debug đồng thời cả hai chương trình, trong đó Server sẽ khởi động trước.

Bước 4. Mở file Program.cs của Client và viết code như sau:

using System;
using System.Net;
using System.Net.Sockets;
using System.Text;
namespace Client
{
    internal class Program
    {
        private static void Main(string[] args)
        {
            Console.Title = "Tcp Client";
            // yêu cầu người dùng nhập ip của server
            Console.Write("Server IP address: ");
            var serverIpStr = Console.ReadLine();
            // chuyển đổi chuỗi ký tự thành object thuộc kiểu IPAddress
            var serverIp = IPAddress.Parse(serverIpStr);
            // yêu cầu người dùng nhập cổng của server
            Console.Write("Server port: ");
            var serverPortStr = Console.ReadLine();
            // chuyển chuỗi ký tự thành biến kiểu int
            var serverPort = int.Parse(serverPortStr);
            // đây là "địa chỉ" của tiến trình server trên mạng
            // mỗi endpoint chứa ip của host và port của tiến trình
            var serverEndpoint = new IPEndPoint(serverIp, serverPort);
            var size = 1024; // kích thước của bộ đệm
            var receiveBuffer = new byte[size]; // mảng byte làm bộ đệm            
            while (true)
            {
                // yêu cầu người dùng nhập một chuỗi
                Console.ForegroundColor = ConsoleColor.Green;
                Console.Write("# Text >>> ");
                Console.ResetColor();
                var text = Console.ReadLine();
                // khởi tạo object của lớp socket để sử dụng dịch vụ Tcp
                // lưu ý SocketType của Tcp là Stream 
                var socket = new Socket(SocketType.Stream, ProtocolType.Tcp);
                // tạo kết nối tới Server
                socket.Connect(serverEndpoint);   
                // biến đổi chuỗi thành mảng byte
                var sendBuffer = Encoding.ASCII.GetBytes(text);
                // gửi mảng byte trên đến tiến trình server
                socket.Send(sendBuffer);
                // không tiếp tục gửi dữ liệu nữa
                socket.Shutdown(SocketShutdown.Send);
                // nhận mảng byte từ dịch vụ Tcp và lưu vào bộ đệm                    
                var length = socket.Receive(receiveBuffer);
                // chuyển đổi mảng byte về chuỗi
                var result = Encoding.ASCII.GetString(receiveBuffer, 0, length);
                // xóa bộ đệm (để lần sau sử dụng cho yên tâm)
                Array.Clear(receiveBuffer, 0, size);
                // không tiếp tục nhận dữ liệu nữa
                socket.Shutdown(SocketShutdown.Receive);
                // đóng socket và giải phóng tài nguyên
                socket.Close();
                // in kết quả ra màn hình
                Console.WriteLine($">>> {result}");
            }
        }
    }
}

Bước 5. Mở file Program.cs của Server và viết code như sau:

using System;
using System.Net;
using System.Net.Sockets;
using System.Text;
namespace Server
{
    internal class Program
    {
        private static void Main(string[] args)
        {
            Console.Title = "Tcp Server";
            // giá trị Any của IPAddress tương ứng với Ip của tất cả các giao diện mạng trên máy
            var localIp = IPAddress.Any;
            // tiến trình server sẽ sử dụng cổng tcp 1308
            var localPort = 1308;
            // biến này sẽ chứa "địa chỉ" của tiến trình server trên mạng
            var localEndPoint = new IPEndPoint(localIp, localPort);
            // tcp sử dụng đồng thời hai socket: 
            // một socket để chờ nghe kết nối, một socket để gửi/nhận dữ liệu
            // socket listener này chỉ làm nhiệm vụ chờ kết nối từ Client
            var listener = new Socket(AddressFamily.InterNetwork, SocketType.Stream, ProtocolType.Tcp);
            // yêu cầu hệ điều hành cho phép chiếm dụng cổng tcp 1308
            // server sẽ nghe trên tất cả các mạng mà máy tính này kết nối tới
            // chỉ cần gói tin tcp đến cổng 1308, tiến trình server sẽ nhận được
            listener.Bind(localEndPoint);
            // bắt đầu lắng nghe chờ các gói tin tcp đến cổng 1308
            listener.Listen(10);
            Console.WriteLine($"Local socket bind to {localEndPoint}. Waiting for request ...");
            var size = 1024;
            var receiveBuffer = new byte[size];
            while (true)
            {
                // tcp đòi hỏi một socket thứ hai làm nhiệm vụ gửi/nhận dữ liệu
                // socket này được tạo ra bởi lệnh Accept
                var socket = listener.Accept();
                Console.WriteLine($"Accepted connection from {socket.RemoteEndPoint}");
                // nhận dữ liệu vào buffer
                var length = socket.Receive(receiveBuffer);
                // không tiếp tục nhận dữ liệu nữa
                socket.Shutdown(SocketShutdown.Receive);
                var text = Encoding.ASCII.GetString(receiveBuffer, 0, length);
                Console.WriteLine($"Received: {text}");
                // chuyển chuỗi thành dạng in hoa
                var result = text.ToUpper();
                var sendBuffer = Encoding.ASCII.GetBytes(result);
                // gửi kết quả lại cho client
                socket.Send(sendBuffer);
                Console.WriteLine($"Sent: {result}");
                // không tiếp tục gửi dữ liệu nữa
                socket.Shutdown(SocketShutdown.Send);
                // đóng kết nối và giải phóng tài nguyên
                Console.WriteLine($"Closing connection from {socket.RemoteEndPoint}rn");
                socket.Close();
                Array.Clear(receiveBuffer, 0, size);
            }
        }
    }
}

Chúng ta hoàn toàn có thể chú ý, code của cả Client và Server đều tái sử dụng phần khung của nội dung thực hành thực tế 1 Udp nhưng thay thế sửa chữa phần tiếp thị quảng cáo Udp bằng Tcp. So sánh với code của thực hành thực tế 1 Udp để thấy được sự độc lạ .

Bước 6. Dịch và chạy thử hệ thống

Ảnh chụp màn hình chương trình tcp client/serverChương trình Client về hình thức vẻ bên ngoài không có gì độc lạ so với chương trình viết ở phần thực hành thực tế 1 của Udp. Tuy nhiên, phần truyền thông online đã đổi khác trọn vẹn .Trong phần tiếp theo tất cả chúng ta sẽ nghiên cứu và phân tích code của Client và Server để hiểu được cách lập trình với socket Tcp .