zoukankan      html  css  js  c++  java
  • 浅谈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;
                    }
                }
            }
        }
    }
  • 相关阅读:
    【高软作业4】:Tomcat 观察者模式解析 之 Lifecycle
    Eclipse 导入 Tomcat 源码
    【高软作业3】:原型化系统 DevTools
    Java Obejct
    Java PriorityQueue
    【高软作业2】:Java IDE调研分析
    GitHub fork 合作开发 快速实现版
    用C#实现天气预报(调用WebService)
    hover和点击事件之间的冲突
    BurpSuite2021系列(三)新建扫描
  • 原文地址:https://www.cnblogs.com/wangyonglai/p/8257477.html
Copyright © 2011-2022 走看看