浅谈TCP通讯

基于Tcp协议的Socket通讯类似于B/S架构,面向连接,但不同的是服务器端可以向客户端主动推送消息。

使用Tcp协议通讯需要具备以下几个条件:

    (1).建立一个套接字(Socket)

    (2).绑定服务器端IP地址及端口号--服务器端

    (3).利用Listen()方法开启监听--服务器端

    (4).利用Accept()方法尝试与客户端建立一个连接--服务器端

    (5).利用Connect()方法与服务器建立连接--客户端

    (5).利用Send()方法向建立连接的主机发送消息

    (6).利用Recive()方法接受来自建立连接的主机的消息(可靠连接)

以下为个人平时编写的实例

TCP服务端实例

using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
using System.Net.Sockets;
using System.Threading;
using System.Net;

namespace TcpServerConsoleApp
{
    class Program
    {
        /// <summary>
        /// 服务器端的监听器
        /// </summary>
        private static TcpListener _tcpl = null;
        /// <summary>
        /// 本机IP地址
        /// </summary>
        private static IPAddress _ip = null;

        private static int _port = 9005;

        static void Main(string[] args)
        {
            GetLocationIp();//获取IP地址
            StartTcpServer();//启动

        }


        private static void GetLocationIp()
        {
            //IP4获取IP地址
            //IPAddress _ip = Dns.GetHostAddresses(Dns.GetHostName())[0];//可能有多个,此时的IP是本地IP

            //如果在IP6的需要以下发送获取IP地址
            IPHostEntry IpEntry = Dns.GetHostEntry(Dns.GetHostName());
            for (int i = 0; i < IpEntry.AddressList.Length; i++)
            {
                //从IP地址列表中筛选出IPv4类型的IP地址
                //AddressFamily.InterNetwork表示此IP为IPv4,
                //AddressFamily.InterNetworkV6表示此地址为IPv6类型
                if (IpEntry.AddressList[i].AddressFamily == System.Net.Sockets.AddressFamily.InterNetwork)
                {
                    _ip = IpEntry.AddressList[i];
                    break;
                }
            }

            
        }

        /// <summary>
        /// 启动TCP服务器
        /// </summary>
        /// <param name="port"></param>
        private static void StartTcpServer()
        {
            try
            {
                _tcpl = new TcpListener(_ip, _port);
                _tcpl.Start();
                Console.WriteLine("服务器已启动,正在监听...
");
                Console.WriteLine(string.Format("服务器IP:{0}	端口号:{1}
", _ip, _port));
                //AcceptSocket 是一个阻止方法,该方法返回可用于发送和接收数据的 Socket。
                //如果希望避免阻止,请使用 Pending 方法来确定传入连接队列中的连接请求是否可用。 
                //返回的 Socket 是使用远程主机的 IP 地址和端口号初始化的。
                //您可以使用 Socket 类中任何可用的 Send 和 Receive 方法与远程主机进行通信。
                //------------使用 Socket 后,请确保调用其 Close 方法。如果应用程序相对简单,-----------
                //请考虑使用 AcceptTcpClient 方法代替 AcceptSocket 方法。
                //TcpClient 提供了一些通过网络在阻止同步模式下发送和接收数据的简单方法。

                Socket newClient = _tcpl.AcceptSocket();//本地TcpListener 接受新的请求 
                //返回的 Socket 是使用远程主机的 IP 地址和端口号初始化的

                //byte[] packetBuff = new byte[10 * 1024];//接收数据缓冲区大小10K
                //newClient.Receive(packetBuff);

                Console.WriteLine("接入客服端:{0}", newClient.RemoteEndPoint.ToString());

                Thread clientThread = new Thread(() => ThrendReciveFunc(newClient));
                clientThread.Start();
            }
            catch
            { }

        }

        /// <summary>
        /// 接收子线程
        /// </summary>
        /// <param name="socketClient"></param>
        private static void ThrendReciveFunc(Socket socketClient)
        {
            while (true)
            {
                try
                {
                    byte[] buffer = new byte[10 * 1024];//接收数据缓冲区
                    int count = socketClient.Receive(buffer);
                    string msg = Encoding.Default.GetString(buffer, 0, count);
                    Console.WriteLine("收到消息:{0}", msg);
                    string sendmsg = "收到消息!";
                    socketClient.Send(Encoding.Default.GetBytes(sendmsg));
                }
                catch (Exception ex)
                {
                    Console.WriteLine(string.Format("出现异常:{0}", ex.Message));
                    Thread.CurrentThread.Abort();//结束该接收线程
                    Console.Read();
                    break;
                }
            }
        }
       



    }
}

TCP客服端实例

using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
using System.Net;
using System.Net.Sockets;
using System.Threading;

namespace TcpClientConsolApp
{
    class Program
    {
        static IPAddress _ip = null;
        static TcpClient _tcpc;
        static NetworkStream Netstream;//提供用于访问网络的基本数据流
        static void Main(string[] args)
        {
            Console.WriteLine("请输入IP地址:");
            GetIpAddr();
            Console.WriteLine("请输入端口号:");
            int port = Convert.ToInt16(Console.ReadLine());
            try
            {
                _tcpc = new TcpClient();
                _tcpc.Connect(_ip, port);
                if (_tcpc != null)
                {
                    Console.WriteLine("连接成功");
                    Netstream = _tcpc.GetStream();
                    Thread recvieThread = new Thread(RecvieFunc);
                    recvieThread.Start();
                    
                    /*发送数据*/
                    while (true)
                    {
                        Console.WriteLine("输入要发送的数据");
                        byte[] msg = Encoding.Default.GetBytes(Console.ReadLine());
                        Netstream.Write(msg, 0, msg.Length);
                    }
                }
                else
                {
                    Console.WriteLine("连接失败!");
                }
            }
            catch
            { }

            Console.Read();

        }

        static void GetIpAddr()
        {
            try
            {
                _ip = IPAddress.Parse(Console.ReadLine());
            }
            catch
            {
 
            }
            if (_ip == null)
            {
                Console.WriteLine("输入IP地址有误,请重新输入");
                GetIpAddr();
            }
        }

        /// <summary>
        /// 接收线程
        /// </summary>
        static void RecvieFunc()
        {
            while (_tcpc.Client.Connected)
            {
                try
                {
                    byte[] buffer = new byte[10 * 1024];
                    int count = _tcpc.Client.Receive(buffer);
                    string msg = Encoding.Default.GetString(buffer, 0, count);
                    Console.WriteLine("接收到信息:{0}", msg);

                }
                catch (Exception ex)
                {
                    Console.WriteLine(string.Format("出现异常:{0}", ex.Message));
                    //Netstream = null;
                    Netstream.Close();
                    Thread.CurrentThread.Abort();
                    break;
                }
            }
        }
    }
}
原文地址:https://www.cnblogs.com/wangyonglai/p/8257477.html