c# – lập trình socket giao tiếp tcp client/server

Trong thiết kế, Socket là một trong những API (Application Programming Interface) cung ứng những cách thức nhằm tiếp xúc trải qua mạng. Trước Khi chính thức lần hiểu và ghi chép một ví dụ giản dị về socket, chúng ta có thể xem thêm bài bác  viết “Networking – Một số định nghĩa cơ bản“ để sở hữu ánh nhìn sơ lược về những định nghĩa cơ phiên bản nhập thiết kế mạng.

Các lớp .Net cơ phiên bản nhập thiết kế mạng

Các lớp này được cung ứng nhập nhì namespace System.Net và System.Net.Sockets. Hai namespace này chứa chấp thật nhiều lớp người sử dụng nhập thiết kế mạng, tuy nhiên trong phạm vi nội dung bài viết tao chỉ quan hoài cho tới những lớp sau::

Bạn đang xem: c# – lập trình socket giao tiếp tcp client/server

Class Namespace Desciption
IPAddress System.Net Provides an Internet Protocol (IP) address.
IPEndPoint System.Net Represents a network endpoint as an IP address and a port number.
TcpListener System.Net.Sockets Listens for connections from TCP network clients.
Socket System.Net.Sockets Implements the Berkeley sockets interface.
TcpClient System.Net.Sockets Provides client connections for TCP network services.
NetworkStream System.Net.Sockets Provides the underlying stream of data for network access.

Kết nối Server-Client với TCP/IP

Khi được chạy, server rất cần phải xác lập rõ ràng địa điểm IP và tiếp tục “lắng nghe” bên trên một port ví dụ. Server tiếp tục trực thuộc hiện trạng này cho tới Khi client gửi cho tới một đòi hỏi liên kết. Sau Khi được server đồng ý, một connection tiếp tục tạo hình được chấp nhận server và client tiếp xúc cùng nhau.

Cụ thể rộng lớn, công việc tổ chức bên trên server và client nhưng mà tao cần thiết triển khai dùng uỷ thác thức TCP/IP nhập C# (có thể chạy server và client bên trên và một máy):

Server:

  1. Tạo một đối tượng người sử dụng System.Net.Sockets.TcpListener để chính thức “lắng nghe” bên trên một cổng toàn cục.
  2. Đợi và đồng ý liên kết kể từ client với cách thức AccepSocket(). Phương thức này trả về một đối tượng người sử dụng System.Net.Sockets.Socket dùng làm gửi và nhận tài liệu.
  3. Thực hiện tại tiếp xúc với client.
  4. Đóng Socket.

Thông thông thường tiến độ này sẽ tiến hành bịa nhập một vòng lặp (lặp lại bước 2) nhằm đồng ý nhiều liên kết đồng thời (sử dụng Thread) hoặc những liên kết theo lần lượt.

Client:

  1. Tạo một đối tượng người sử dụng System.Net.Sockets.TcpClient
  2. Kết nối cho tới server với địa điểm và port xác lập với cách thức TcpClient.Connect()
  3. Lấy luồng (stream) tiếp xúc vày cách thức TcpClient.GetStream().
  4. Thực hiện tại tiếp xúc với server.
  5. Đóng luồng và socket.

Quy trình này rất có thể được minh họa theo dõi quy mô sau:

Example v1: Gửi nhận tài liệu dạng byte[]

Lớp NetworkStream và  Socket cung ứng những cách thức gửi và nhận tài liệu dạng mảng byte. Vì vậy bạn phải triển khai công việc quy đổi tài liệu thanh lịch dạng byte và ngược lại. Trong ví dụ sau tôi dùng tài liệu dạng văn phiên bản ASCII nhập console, và người sử dụng những lớp bên trong namespace System.Text nhằm quy đổi. Có nhì cơ hội chúng ta có thể áp dụng:

–       Dùng những static property của lớp abstract System.Text.Encoding với những cách thức GetString() và GetBytes().

–       Tạo đối tượng người sử dụng sở hữu loại XXXEncoding (thừa tiếp kể từ System.Text.Encoding). Ví dụ: UTF8Encoding, ASCIIEncoding,…

Một ví dụ gửi nhận tài liệu giản dị nhất dùng TCPListener, Socket (phía server) và TCPClient, NetworkStream (phía client) dạng mảng byte với địa điểm loop-back 127.0.0.1 bên trên và một máy.

Tạo nhì dự án công trình console là Y2Server và Y2Client với nội dung sau:

Y2Server.cs (v1):

using System;
using System.Text;
using System.Net;
using System.Net.Sockets;

public class Y2Server {

    private const int BUFFER_SIZE=1024;
    private const int PORT_NUMBER=9999;

    static ASCIIEncoding encoding=new ASCIIEncoding();

    public static void Main() {
        try {
            IPAddress address = IPAddress.Parse("127.0.0.1");

            TcpListener listener=new TcpListener(address,PORT_NUMBER);

            // 1. listen
            listener.Start();

            Console.WriteLine("Server started on "+listener.LocalEndpoint);
            Console.WriteLine("Waiting for a connection...");

            Socket socket=listener.AcceptSocket();
            Console.WriteLine("Connection received from " + socket.RemoteEndPoint);

            // 2. receive
            byte[] data=new byte[BUFFER_SIZE];
            socket.Receive(data);

            string str=encoding.GetString(data);

            // 3. send
            socket.Send(encoding.GetBytes("Hello "+str));

            // 4. close
            socket.Close();
            listener.Stop();

        }
        catch (Exception ex) {
            Console.WriteLine("Error: " + ex);
        }
        Console.Read();
    }
}

Y2Client.cs (v1):

using System;
using System.IO;
using System.Net;
using System.Text;
using System.Net.Sockets;

public class Y2Client{

    private const int BUFFER_SIZE=1024;
    private const int PORT_NUMBER=9999;

    static ASCIIEncoding encoding= new ASCIIEncoding();

    public static void Main() {

        try {
            TcpClient client = new TcpClient();

            // 1. connect
            client.Connect("127.0.0.1",PORT_NUMBER);
            Stream stream = client.GetStream();

            Console.WriteLine("Connected đồ sộ Y2Server.");
            Console.Write("Enter your name: ");

            string str = Console.ReadLine();

            // 2. send
            byte[] data=encoding.GetBytes(str);

            stream.Write(data,0,data.Length);

            // 3. receive
            data =new byte[BUFFER_SIZE];
            stream.Read(data,0,BUFFER_SIZE);

            Console.WriteLine(encoding.GetString(data));

              // 4. Close
stream.Close();
            client.Close();
        }

        catch (Exception ex) {
            Console.WriteLine("Error: " + ex);
        }

        Console.Read();
    }
}

Để đánh giá ví dụ, các bạn chạy server trước, hành lang cửa số console của server tiếp tục hiển thị:

Xem thêm: mẫu xác nhận người phụ thuộc giảm trừ gia cảnh

Server started on 127.0.0.1:9999

Waiting for a connection…

Tiếp cho tới mang đến chạy client, nếu như liên kết thành công xuất sắc, server tiếp tục hiển thị tăng loại thông tin tương tự động như sau:

Connection received from 127.0.0.1:2578

Chuyển qua loa hành lang cửa số console của client và nhập thương hiệu của doanh nghiệp nhập, nếu như có được tài liệu, server tiếp tục gửi trả lại loại thông điệp “Hello [Your Name]”

Connected đồ sộ Y2Server.

Enter your name: Yin Yang

Hello Yin Yang

Ngay sau công đoạn này, cả server và client đều triển khai đóng góp liên kết.

Example v2: Sử dụng StreamReader và StreamWriter

Sẽ tiện lợi rộng lớn nếu như tao dùng StreamReader và StreamWriter nhằm gửi nhận tài liệu nhưng mà ko cần thiết bước quy đổi tương hỗ mảng byte. Các đối tượng người sử dụng StreamReader và StreamWriter rất có thể được khởi tạo nên thẳng kể từ NetworkStream. Thuộc tính AutoFlush của StreamWriter thông thường được bịa là true nhằm tự động hóa gửi tài liệu nhưng mà ko cần thiết đợi cỗ đệm tràn hoặc các bạn nên gọi tay chân cách thức Flush().

Ví dụ sau dùng vòng lặp nhằm triển khai gửi nhận tài liệu liên tiếp thân thiết server/client cho tới Khi client nhập nhập chuỗi “exit”:

 Y2Server.cs (v2):

using System;
using System.IO;
using System.Net;
using System.Net.Sockets;
using System.Text;

public class Y2Server {

    private const int BUFFER_SIZE=1024;
    private const int PORT_NUMBER=9999;

    static ASCIIEncoding encoding=new ASCIIEncoding();

    public static void Main() {
        try {
            IPAddress address = IPAddress.Parse("127.0.0.1");

            TcpListener listener=new TcpListener(address,PORT_NUMBER);

            // 1. listen
            listener.Start();

            Console.WriteLine("Server started on "+listener.LocalEndpoint);
            Console.WriteLine("Waiting for a connection...");

            Socket socket=listener.AcceptSocket();
            Console.WriteLine("Connection received from " + socket.RemoteEndPoint);

            var stream = new NetworkStream(socket);
            var reader=new StreamReader(stream);
            var writer=new StreamWriter(stream);
            writer.AutoFlush=true;

            while(true)
            {
                // 2. receive
                string str=reader.ReadLine();
                if(str.ToUpper()=="EXIT")
                {
                    writer.WriteLine("bye");
                    break;
                }
                // 3. send
                writer.WriteLine("Hello "+str);
            }
            // 4. close
            stream.Close();
            socket.Close();
            listener.Stop();
        }
        catch (Exception ex) {
            Console.WriteLine("Error: " + ex);
        }
        Console.Read();
    }
}

Y2Client.cs (v2):

using System;
using System.IO;
using System.Net;
using System.Text;
using System.Net.Sockets;

public class Y2Client{

    private const int BUFFER_SIZE=1024;
    private const int PORT_NUMBER=9999;

    static ASCIIEncoding encoding= new ASCIIEncoding();

    public static void Main() {

        try {
            TcpClient client = new TcpClient();

            // 1. connect
            client.Connect("127.0.0.1",PORT_NUMBER);
            Stream stream = client.GetStream();

            Console.WriteLine("Connected đồ sộ Y2Server.");
            while(true)
            {
                Console.Write("Enter your name: ");

                string str = Console.ReadLine();
                var reader=new StreamReader(stream);
                var writer=new StreamWriter(stream);
                writer.AutoFlush=true;

                // 2. send
                writer.WriteLine(str);

                // 3. receive
                str=reader.ReadLine();
                Console.WriteLine(str);
                if(str.ToUpper()=="BYE")
                    break;
            }
            // 4. close
            stream.Close();
            client.Close();
        }

        catch (Exception ex) {
            Console.WriteLine("Error: " + ex);
        }

        Console.Read();
    }
}

Bạn  chạy ví dụ này tương tự như ví dụ thứ nhất và gõ ‘exit’ nhập client nhằm bay phần mềm.

Xem thêm: dàn ý cảm nhận về nhân vật ngô tử văn

Cập nhật: (27/9/2010)

Thay thay đổi BUFFER_SIZE kể từ 100 lên 1024. (cảm ơn các bạn hoang)

https://tamkyrt.com