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

Trong xây dựng, Socket là một trong những API (Application Programming Interface) cung ứng những công 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à đơn giản về socket, chúng ta cũng có thể tìm hiểu thêm bài xích  viết “Networking – Một số định nghĩa cơ bản“ để sở hữu tầm nhìn sơ lược về những định nghĩa cơ bạn dạng nhập xây dựng mạng.

Các lớp .Net cơ bạn dạng nhập xây dựng 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 xây dựng 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 vị trí 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 tình 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 gật đầu, 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 tuy nhiên 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 bộ.
  2. Đợi và gật đầu liên kết kể từ client với công 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 nay 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 đặt nhập một vòng lặp (lặp lại bước 2) nhằm gật đầu 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 vị trí và port xác lập với công thức TcpClient.Connect()
  3. Lấy luồng (stream) tiếp xúc vị công thức TcpClient.GetStream().
  4. Thực hiện nay tiếp xúc với server.
  5. Đóng luồng và socket.

Quy trình này hoàn toàn có thể được minh họa theo đuổ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ông 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 quý phái dạng byte và ngược lại. Trong ví dụ sau tôi dùng tài liệu dạng văn bạn dạng 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ũng có thể áp dụng:

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

–       Tạo đối tượng người sử dụng đem loại XXXEncoding (thừa nối 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ị và đơn giản nhất dùng TCPListener, Socket (phía server) và TCPClient, NetworkStream (phía client) dạng mảng byte với vị trí 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 to lớn 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ụ, chúng ta 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: đơn đề nghị đổi, cấp lại giấy phép lái xe

Server started on 127.0.0.1:9999

Waiting for a connection…

Tiếp cho tới đế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ị thêm thắt loại thông tin tương tự động như sau:

Connection received from 127.0.0.1:2578

Chuyển qua chuyện hành lang cửa số console của client và nhập thương hiệu của công ty 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 to lớn 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 tuy nhiên ko cần thiết bước quy đổi hỗ tương mảng byte. Các đối tượng người sử dụng StreamReader và StreamWriter hoàn toàn có thể được khởi tạo ra thẳng kể từ NetworkStream. Thuộc tính AutoFlush của StreamWriter thông thường được bịa đặt là true nhằm tự động hóa gửi tài liệu tuy nhiên ko cần thiết đợi cỗ đệm tràn hoặc chúng ta nên gọi tay chân công 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 thuộc 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 to lớn 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ựa như ví dụ thứ nhất và gõ ‘exit’ nhập client nhằm bay phần mềm.

Xem thêm: tranh vẽ tạo dáng và trang trí thời trang lớp 9

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

Thay thay đổi BUFFER_SIZE kể từ 100 lên 1024. (cảm ơn chúng ta hoang)

https://angiangtourism.net