Aplicación del protocolo TCP / IP basado en C # (1)

1. Antecedentes y concepto

1. Ethernet estándar

Ethernet fue desarrollado con éxito por Palo Alto Research Center de Xerox Corporation en 1975, y su tecnología central se originó en la red ALOHA. En la actualidad, Ethernet se refiere al grupo de productos de red de área local (LAN) que cumple con el estándar IEEE 802.3. IEEE 802.3 es un conjunto de estándares del Instituto de Ingenieros Eléctricos y Electrónicos (IEEE) que definen la capa física y la capa de enlace de datos de cableado Control de acceso a medios Ethernet. Explica las reglas para configurar una red Ethernet y cómo varios elementos de la red cooperan entre sí. Ethernet se divide en:
1. Ethernet estándar: la primera Ethernet de 10 Mbps se llama Ethernet estándar, que es una red de área local de tipo bus que consta de un cable coaxial y una tarjeta de red (adaptador de red). .
Inserte la descripción de la imagen aquí
El envío y la recepción de datos se completan a través del protocolo CSMA / CD El proceso se puede resumir brevemente en cuatro puntos: escuchar primero y enviar, escuchar mientras se envía, detener el conflicto, retrasar la retransmisión .
2. El bus Ethernet se amplía mediante repetidores y puentes.
Repeater (Repeater), también llamado repetidor, amplifica la señal atenuada en el medio de transmisión para aumentar la distancia de transmisión del cable.
Bridge, también conocido como puente, es un dispositivo de almacenamiento y reenvío. Funciona en la capa de enlace de datos.Cuando recibe una trama, primero verifica la dirección MAC de destino de la trama y luego determina a qué puerto se reenvía la trama.
Hay muchos tipos de Ethernet, incluido Ethernet basado en concentrador, Ethernet basado en conmutador, etc., y ahora se ha desarrollado a cien mil Gigabit Ethernet. .

2. Ethernet industrial

Ethernet industrial generalmente significa que es técnicamente compatible con Ethernet comercial (es decir, el estándar IEEE802.3), pero en el diseño del producto, puede cumplir con los requisitos de los sitios industriales en términos de selección de materiales, resistencia del producto, aplicabilidad y rendimiento en tiempo real. necesitar.
Actualmente incluye 4 protocolos principales: HSE, Modbus TCP / IP, ProfINet, Ethernet / IP.
Foundation Fieldbus FF lanzó la especificación Ethernet en 2000, llamada HSE (Ethernet de alta velocidad).
El protocolo Modbus TCP / IP fue lanzado por Schneider, que integra tramas Modbus en tramas TCP de una manera muy sencilla y combina Modbus con Ethernet y TCP / IP.
La alemana Siemens lanzó la solución de red ProfiNet en 2001, que combina el Profibus original con la tecnología de Internet. ProfiNet utiliza el protocolo TCP / IP estándar más la capa de aplicación RPC / DCOM para completar la comunicación y el direccionamiento de red entre nodos.
Ethernet / IP es un sistema de protocolo adecuado para aplicaciones de entorno industrial, basado en el protocolo CIP (Control and Information Proto-Col). Es un protocolo orientado a objetos que puede garantizar la transmisión efectiva de información de E / S implícita (control) en tiempo real e información explícita (incluida la configuración, el ajuste de parámetros, el diagnóstico, etc.) en la red.
El equipo Ethernet industrial incluye las siguientes partes importantes:
1. Concentrador Ethernet industrial
2. Conmutador no administrado
Ethernet industrial 3. Conmutador administrado Ethernet
industrial 4. Conmutador redundante administrado Ethernet industrial

3. Protocolo TCP / IP

Inserte la descripción de la imagen aquí
La tabla anterior muestra las funciones y protocolos básicos del protocolo de red. El protocolo TCP (Protocolo de control de transmisión) está en la capa de transporte y el protocolo IP (Protocolo de Internet) está en la capa de red.
1. Protocolo TCP: es un protocolo de comunicación de capa de transporte basado en flujo de bytes confiable y orientado a la conexión. Es un protocolo de transmisión especialmente diseñado para proporcionar un flujo de bytes confiable de extremo a extremo en una red de Internet no confiable. Una internetwork es muy diferente de una sola red, porque diferentes partes de la internetwork pueden tener topologías, anchos de banda, retrasos, tamaños de paquetes y otros parámetros muy diferentes. El objetivo del diseño de TCP es poder adaptarse dinámicamente a estas características de Internet y tener robustez ante diversas fallas.
Inserte la descripción de la imagen aquí
Protocolo IP
2. Protocolo IP: es un protocolo para la transferencia de información entre redes, que puede transferir paquetes de información IP desde un dispositivo de origen (como la computadora de un usuario) a un dispositivo de destino (como un servidor www en un determinado departamento). Su propósito es resolver los problemas de Internet y realizar la interconexión e interoperabilidad de redes heterogéneas y a gran escala; el segundo es dividir la relación de acoplamiento entre las aplicaciones de red de nivel superior y las tecnologías de red de nivel inferior para facilitar el desarrollo independiente de las dos.
3. Apretón de manos de tres vías, ruptura de cuatro veces
Inserte la descripción de la imagen aquí
, SYN: Sincronizar números de secuencia, que es la señal de apretón de manos utilizada cuando TCP / IP establece una conexión. ACK: ACK (carácter de reconocimiento) es el carácter de confirmación En la comunicación de datos, un carácter de control de transmisión enviado por la estación receptora a la estación emisora. Indica que se ha confirmado que los datos enviados se han recibido correctamente.
FIN_WAIT: FIN_WAIT_1 y FIN_WAIT_2 ambos indican que están esperando el mensaje FIN del otro.
4. Enchufes La
capa de aplicación y la capa de transporte están separadas por enchufes. El zócalo contiene dos piezas de información: la información del puerto local (dirección local y número de puerto) conectado al control remoto y la información del puerto remoto (dirección remota y número de puerto) conectado al control remoto.
5. TcpClient y TcpListener
.NET proporciona estas dos clases para encapsular la programación de sockets.
Inserte la descripción de la imagen aquí
Generalmente, la parte que inicia la conexión se llama cliente y la otra se llama servidor, ahora se puede concluir que el servidor siempre está usando la clase TcpListener porque necesita establecer una conexión inicial.

IPAddress ip = new IPAddress(new byte[] { 127, 0, 0, 1 });
            TcpListener listener = new TcpListener(ip, 8500);

            listener.Start();           // 开始侦听
            Console.WriteLine("Start Listening ...");

Puerto 8500: proporciona interfaces HTTP para obtener listas de servicios, servicios de registro y servicios de cancelación; proporciona servicios de interfaz de usuario, utilizando cmd: netstat -a;
cada vez que se crea un nuevo TcpClient, es equivalente a crear un nuevo socket Socket para comunicarse con el servidor Para la comunicación, .Net asignará automáticamente un número de puerto a este socket
Al crear una instancia del tipo TcpClient, puede especificar la dirección y el número de puerto del servidor remoto en el constructor. De esta forma, al mismo tiempo que se crea, se enviará una solicitud de conexión ("handshake") al servidor remoto, una vez que lo haga, se establecerá la conexión entre ambos. También puede usar el constructor sin parámetros sobrecargado para crear un objeto, y luego llamar al método Connect () y pasar la dirección del servidor remoto y el número de puerto en el método Connect () para establecer una conexión con el servidor, sin importar si usar un constructor parametrizado Conectarse al servidor, o establecer una conexión con el servidor a través del método Connect (), es un método sincrónico (o bloqueo, llamado bloque en inglés).
6. Puerto de comunicación
Una vez establecida la conexión con el servidor, podemos enviar y recibir datos a través de esta conexión. Los datos se transfieren entre puertos y puertos en forma de flujos. Debido a que casi cualquier objeto se puede guardar en el flujo, cualquier tipo de datos se puede transferir entre el cliente y el servidor. Para el cliente, escribir datos en el flujo significa transmitir datos al servidor; leer datos del flujo significa recibir datos del servidor. Para el servidor, escribir datos en el flujo significa enviar datos al cliente; leer datos del flujo significa recibir datos del cliente.

Dos, ejemplo

1. Establezca una conexión entre el cliente y el servidor.

Cree dos programas de consola respectivamente.

class Client
    {
        static void Main(string[] args)
        {
            TcpClient client = new TcpClient();
            try
            {
                client.Connect("local", 8500);  
            }
            catch (Exception ex)
            {
                Console.WriteLine(ex.Message);
                return;
            }
            Console.WriteLine("Server Connected!{0} --> {1}",client.Client.LocalEndPoint, client.Client.RemoteEndPoint);
        }
    }
static void Main(string[] args)
        {
            Console.WriteLine("Server is running ... ");
            IPAddress ip = new IPAddress(new byte[] { 127, 0, 0, 1 });
            TcpListener listener = new TcpListener(ip, 8500);
            listener.Start();       
            Console.WriteLine("Start Listening ...");

            TcpClient remoteClient = listener.AcceptTcpClient();
            Console.WriteLine("Client Connected!{0} <-- {1}",remoteClient.Client.LocalEndPoint, remoteClient.Client.RemoteEndPoint);                
        }

El resultado no se muestra, tuvo éxito de todos modos y las dos aplicaciones establecieron una conexión.

2. Un cliente realiza varias solicitudes

static void Main(string[] args)
        {
            const int BufferSize = 8192;    
            Console.WriteLine("Server is running ... ");
            IPAddress ip = new IPAddress(new byte[] { 127, 0, 0, 1 });
            TcpListener listener = new TcpListener(ip, 8500);
            listener.Start(); 
            Console.WriteLine("Start Listening ...");

            TcpClient remoteClient = listener.AcceptTcpClient();
            Console.WriteLine("Client Connected!{0} <-- {1}",remoteClient.Client.LocalEndPoint, remoteClient.Client.RemoteEndPoint);
            NetworkStream streamToClient = remoteClient.GetStream();
            do
            {
                byte[] buffer = new byte[BufferSize];
                int bytesRead = streamToClient.Read(buffer, 0, BufferSize);
                Console.WriteLine("Reading data, {0} bytes ...", bytesRead);

                string msg = Encoding.Unicode.GetString(buffer, 0, bytesRead);
                Console.WriteLine("Received: {0}", msg);
            } while (true);
        }
class Client
    {
        static void Main(string[] args)
        {
            Console.WriteLine("Client Running ...");
            TcpClient client;
            try
            {
                client = new TcpClient();
                client.Connect("localhost", 8500);      
            catch (Exception ex)
            {
                Console.WriteLine(ex.Message);
                return;
            }
            Console.WriteLine("Server Connected!{0} --> {1}",
                client.Client.LocalEndPoint, client.Client.RemoteEndPoint);
           
            NetworkStream streamToServer = client.GetStream();
            ConsoleKey key;
            Console.WriteLine("Menu: M - Send, G - Exit");
            do
            {
                key = Console.ReadKey(true).Key;

                if (key == ConsoleKey.M)
                {
                    Console.Write("Input the message: ");
                    string msg = Console.ReadLine();

                    byte[] buffer = Encoding.Unicode.GetBytes(msg);    
                    streamToServer.Write(buffer, 0, buffer.Length);  
                    Console.WriteLine("Sent: {0}", msg);
                }
            } while (key != ConsoleKey.G);
            //client.Close();
        }
    }

### 3. El servidor devuelve los caracteres procesados
El servidor intercepta la cadena de caracteres transmitida por el cliente y la envía de vuelta al cliente.

static void Main(string[] args)
        {
            const int BufferSize = 8192;   
            ConsoleKey key;

            Console.WriteLine("Server is running ... ");
            IPAddress ip = new IPAddress(new byte[] { 127, 0, 0, 1 });
            TcpListener listener = new TcpListener(ip, 8500);
            listener.Start();           
            Console.WriteLine("Start Listening ...");

            TcpClient remoteClient = listener.AcceptTcpClient();
            Console.WriteLine("Client Connected!{0} <-- {1}",
                remoteClient.Client.LocalEndPoint, remoteClient.Client.RemoteEndPoint);

            NetworkStream streamToClient = remoteClient.GetStream();
            do
            {
                byte[] buffer = new byte[BufferSize];
                int bytesRead;
                try
                {
                    lock (streamToClient)
                    {
                        bytesRead = streamToClient.Read(buffer, 0, BufferSize);
                    }
                    if (bytesRead == 0) throw new Exception("读取到0字节");
                    Console.WriteLine("Reading data, {0} bytes ...", bytesRead);
                    string msg = Encoding.Unicode.GetString(buffer, 0, bytesRead);
                    Console.WriteLine("Received: {0}", msg);
                    msg = msg.Substring(2);
                    buffer = Encoding.Unicode.GetBytes(msg);
                    lock (streamToClient)
                    {
                        streamToClient.Write(buffer, 0, buffer.Length);
                    }
                    Console.WriteLine("Sent: {0}", msg);
                }
                catch (Exception ex)
                {
                    Console.WriteLine(ex.Message);
                    break;
                }
            } while (true);

            streamToClient.Dispose();
            remoteClient.Close();

            Console.WriteLine("\n\n输入\"Q\"键退出。");
            do
            {
                key = Console.ReadKey(true).Key;
            } while (key != ConsoleKey.Q);
        }
class Client
    {
        static void Main(string[] args)
        {
            Console.WriteLine("Client Running ...");
            TcpClient client;
            ConsoleKey key;
            const int BufferSize = 8192;
            try
            {
                client = new TcpClient();
                client.Connect("localhost", 8500);   
            }
            catch (Exception ex)
            {
                Console.WriteLine(ex.Message);
                return;
            }
            Console.WriteLine("Server Connected!{0} --> {1}",
                client.Client.LocalEndPoint, client.Client.RemoteEndPoint);           
            NetworkStream streamToServer = client.GetStream();
            Console.WriteLine("Menu: S - Send, X - Exit");
            do
            {
                key = Console.ReadKey(true).Key;

                if (key == ConsoleKey.S)
                {
                    Console.Write("Input the message: ");
                    string msg = Console.ReadLine();
                    byte[] buffer = Encoding.Unicode.GetBytes(msg);   
                    try
                    {
                        lock (streamToServer)
                        {
                            streamToServer.Write(buffer, 0, buffer.Length);
                        }
                        Console.WriteLine("Sent: {0}", msg);
                        int bytesRead;
                        buffer = new byte[BufferSize];
                        lock (streamToServer)
                        {
                            bytesRead = streamToServer.Read(buffer, 0, BufferSize);
                        }
                        msg = Encoding.Unicode.GetString(buffer, 0, bytesRead);
                        Console.WriteLine("Received: {0}", msg);
                    }
                    catch (Exception ex)
                    {
                        Console.WriteLine(ex.Message);
                        break;
                    }
                }
            } while (key != ConsoleKey.X);
            streamToServer.Dispose();
            client.Close();
            Console.WriteLine("\n\n输入\"Q\"键退出。");
            do
            {
                key = Console.ReadKey(true).Key;
            } while (key != ConsoleKey.Q);        
        }
    }

Tres, descripción del estado del puerto TCP

1.Estado de ESCUCHANDO

El servidor FTP (Protocolo de transferencia de archivos) permanece en este estado cuando se inicia, hasta que la conexión con el cliente es exitosa.

2.Estado ESTABLECIDO

Es en este estado cuando la conexión es exitosa, lo que significa que los dos extremos se están comunicando.

Estado 3.CLOSE_WAIT

La otra parte cierra activamente la conexión o la conexión se interrumpe debido a una red anormal. Se convertirá en este estado.

Estado 4.TIME_WAIT

Llame activamente a close () para desconectarse, y el estado se convierte en TIME_WAIT después de recibir la confirmación de la otra parte. El protocolo TCP estipula que el estado TIME_WAIT continuará durante 2MSL (el doble de la vida útil máxima del segmento) para garantizar que el estado de la conexión anterior no afecte a la nueva conexión.

5.Estado SYN_SENT

El estado SYN_SENT significa que se solicita una conexión. Cuando desee acceder a los servicios de otras computadoras, primero debe enviar una señal de sincronización al puerto. En este momento, el estado es SYN_SENT. Si la conexión es exitosa, se convertirá en ESTABLECIDO En este momento, el estado SYN_SENT es muy corto. Si encuentra que hay demasiados SYN_SENT y se están enviando a diferentes equipos, es posible que el equipo esté infectado.

Cuatro, resumen

Resumir Socket:
1. Establezca una conexión entre el servidor y el cliente.
2. El cliente envía un mensaje al servidor.
3. El servidor recibe la conexión del cliente.
4. El servidor procesa el mensaje y lo envía al cliente.
5. El cliente recibe el mensaje.
6. Fin.

Artículo de referencia: Protocolo de red de siete capas
Ethernet
- Programación de red del protocolo TCP / IP

Supongo que te gusta

Origin blog.csdn.net/baidu_35536188/article/details/114291257
Recomendado
Clasificación