C#基于Socket套接字的网络通信封装

本文为大家分享了C#基于Socket套接字的网络通信封装代码,供大家参考,具体内容如下

摘要

之所以要进行Socket套接字通信库封装,主要是直接使用套接字进行网络通信编程相对复杂,特别对于初学者而言。实际上微软从.net 2.0开始已经提供了TCP、UDP通信高级封装类如下:

TcpListener
TcpClient
UdpClient

微软从.net 4.0开始提供基于Task任务的异步通信接口。而直接使用socket封装库,很多socket本身的细节没办法自行控制,本文目就是提供一种socket的封装供参考。文中展示部分封装了TCP通信库,UDP封装也可触类旁通:

CusTcpListener
CusTcpClient

TCP服务端

TCP服务端封装了服务端本地绑定、监听、接受客户端连接,并提供了网络数据流的接口。完整代码:

public class CusTcpListener
    {
        private IPEndPoint mServerSocketEndPoint;
        private Socket mServerSocket;
        private bool isActive;

        public Socket Server
        {
            get { return this.mServerSocket; }
        }
        protected bool Active
        {
            get { return this.isActive; }
        }
        public EndPoint LocalEndpoint
        {
            get
            {
                if (!this.isActive)
                {
                    return this.mServerSocketEndPoint;
                }
                return this.mServerSocket.LocalEndPoint;
            }
        }
        public NetworkStream DataStream
        {
            get
            {
                NetworkStream networkStream = null;
                if (this.Server.Connected)
                {
                    networkStream = new NetworkStream(this.Server, true);
                }
                return networkStream;
            }
        }

        public CusTcpListener(IPEndPoint localEP)
        {
            this.mServerSocketEndPoint = localEP;
            this.mServerSocket = new Socket(this.mServerSocketEndPoint.AddressFamily, SocketType.Stream, ProtocolType.Tcp);
        }

        public CusTcpListener(string localaddr, int port)
        {
            if (localaddr == null)
            {
                throw new ArgumentNullException("localaddr");
            }
            this.mServerSocketEndPoint = new IPEndPoint(IPAddress.Parse(localaddr), port);
            this.mServerSocket = new Socket(this.mServerSocketEndPoint.AddressFamily, SocketType.Stream, ProtocolType.Tcp);
        }

        public CusTcpListener(int port)
        {
            this.mServerSocketEndPoint = new IPEndPoint(IPAddress.Any, port);
            this.mServerSocket = new Socket(this.mServerSocketEndPoint.AddressFamily, SocketType.Stream, ProtocolType.Tcp);
        }

        public void Start()
        {
            this.Start(int.MaxValue);
        }
        /// <summary>
        /// 开始服务器监听
        /// </summary>
        /// <param name="backlog">同时等待连接的最大个数(半连接队列个数限制)</param>
        public void Start(int backlog)
        {
            if (backlog > int.MaxValue || backlog < 0)
            {
                throw new ArgumentOutOfRangeException("backlog");
            }
            if (this.mServerSocket == null)
            {
                throw new NullReferenceException("套接字为空");
            }
            this.mServerSocket.Bind(this.mServerSocketEndPoint);
            this.mServerSocket.Listen(backlog);
            this.isActive = true;
        }
        public void Stop()
        {
            if (this.mServerSocket != null)
            {
                this.mServerSocket.Close();
                this.mServerSocket = null;
            }
            this.isActive = false;
            this.mServerSocket = new Socket(this.mServerSocketEndPoint.AddressFamily, SocketType.Stream, ProtocolType.Tcp);
        }

        public Socket AcceptSocket()
        {
            Socket socket = this.mServerSocket.Accept();
            return socket;
        }

        public CusTcpClient AcceptTcpClient()
        {
            CusTcpClient tcpClient = new CusTcpClient(this.mServerSocket.Accept());
            return tcpClient;
        }
    }

TCP客户端

TCP客户端封装了客户端本地绑定、连接服务器,并提供了网络数据流的接口。完整代码:

public class CusTcpClient : IDisposable
    {
        public Socket Client { get; set; }
        protected bool Active { get; set; }
        public IPEndPoint ClientSocketEndPoint { get; set; }
        public bool IsConnected { get { return this.Client.Connected; } }
        public NetworkStream DataStream
        {
            get
            {
                NetworkStream networkStream = null;
                if (this.Client.Connected)
                {
                    networkStream = new NetworkStream(this.Client, true);
                }
                return networkStream;
            }
        }

        public CusTcpClient(IPEndPoint localEP)
        {
            if (localEP == null)
            {
                throw new ArgumentNullException("localEP");
            }
            this.Client = new Socket(localEP.AddressFamily, SocketType.Stream, ProtocolType.Tcp);
            this.Active = false;
            this.Client.Bind(localEP);
            this.ClientSocketEndPoint = localEP;
        }

        public CusTcpClient(string localaddr, int port)
        {
            if (localaddr == null)
            {
                throw new ArgumentNullException("localaddr");
            }
            IPEndPoint localEP = new IPEndPoint(IPAddress.Parse(localaddr), port);
            this.Client = new Socket(localEP.AddressFamily, SocketType.Stream, ProtocolType.Tcp);
            this.Active = false;
            this.Client.Bind(localEP);
            this.ClientSocketEndPoint = localEP;
        }
        internal CusTcpClient(Socket acceptedSocket)
        {
            this.Client = acceptedSocket;
            this.Active = true;
            this.ClientSocketEndPoint = (IPEndPoint)this.Client.LocalEndPoint;
        }

        public void Connect(string address, int port)
        {
            if (address == null)
            {
                throw new ArgumentNullException("address");
            }
            IPEndPoint remoteEP = new IPEndPoint(IPAddress.Parse(address), port);
            this.Connect(remoteEP);
        }

        public void Connect(IPEndPoint remoteEP)
        {
            if (remoteEP == null)
            {
                throw new ArgumentNullException("remoteEP");
            }
            this.Client.Connect(remoteEP);
            this.Active = true;
        }

        public void Close()
        {
            this.Dispose(true);
        }
        protected virtual void Dispose(bool disposing)
        {
            if (disposing)
            {
                IDisposable dataStream = this.DataStream;
                if (dataStream != null)
                {
                    dataStream.Dispose();
                }
                else
                {
                    Socket client = this.Client;
                    if (client != null)
                    {
                        client.Close();
                        this.Client = null;
                    }
                }
                GC.SuppressFinalize(this);
            }
        }

        public void Dispose()
        {
            this.Dispose(true);
        }
    }

通信实验

控制台程序试验,服务端程序:

class Program
    {
        static void Main(string[] args)
        {
            Thread listenerThread = new Thread(ListenerClientConnection);
            listenerThread.IsBackground = true;
            listenerThread.Start();

            Console.ReadKey();
        }

        private static void ListenerClientConnection()
        {
            CusTcpListener tcpListener = new CusTcpListener("127.0.0.1", 5100);
            tcpListener.Start();
            Console.WriteLine("等待客户端连接……");
            while (true)
            {
                CusTcpClient tcpClient = tcpListener.AcceptTcpClient();

                Console.WriteLine("客户端接入,ip={0} port={1}",
                    tcpClient.ClientSocketEndPoint.Address, tcpClient.ClientSocketEndPoint.Port);
                Thread thread = new Thread(DataHandleProcess);
                thread.IsBackground = true;
                thread.Start(tcpClient);
            }
        }

        private static void DataHandleProcess(object obj)
        {
            CusTcpClient tcpClient = (CusTcpClient)obj;
            StreamReader streamReader = new StreamReader(tcpClient.DataStream, Encoding.Default);
            Console.WriteLine("等待客户端输入:");
            while (true)
            {
                try
                {
                    string receStr = streamReader.ReadLine();
                    Console.WriteLine(receStr);
                }
                catch (Exception)
                {
                    Console.WriteLine("断开连接");
                    break;
                }
                Thread.Sleep(5);
            }
        }
    }

客户端程序:

class Program
    {
        static void Main(string[] args)
        {
            Thread listenerThread = new Thread(UserProcess);
            listenerThread.IsBackground = true;
            listenerThread.Start();

            Console.ReadKey();
        }

        private static void UserProcess()
        {
            Console.WriteLine("连接服务器");
            CusTcpClient tcpClient = new CusTcpClient("127.0.0.1", 5080);
            tcpClient.Connect("127.0.0.1", 5100);

            Console.WriteLine("开始和服务器通信");
            StreamWriter sw = new StreamWriter(tcpClient.DataStream, Encoding.Default);
            sw.AutoFlush = true;
            while (true)
            {
                for (int i = 0; i < 10; i++)
                {
                    string str = string.Format("第{0}次,内容:{1}", i, "测试通信");
                    Console.WriteLine("发送数据:{0}", str);
                    sw.WriteLine(str);
                }
                break;
            }
        }
    }

通信成功:

通过本次封装演示可实现基于Socket的通信库封装,目的就是使用Socket通信库让应用开发人员在进行网络通讯编程时无需关心底层通讯机制,而只关心应用层的开发,让开发变得更简洁。当然UDP封装类似,可自行设计。当然本文只是一种示例,实际使用可使用.net自带封装库或自定义封装。

补充:目前有很多优秀的开源Socket框架,比如SuperSocketFastSocket等。

以上就是本文的全部内容,希望对大家的学习有所帮助,也希望大家多多支持我们。

(0)

相关推荐

  • 使用C#实现基于TCP和UDP协议的网络通信程序的基本示例

    C#中使用TCP通信 TCP通信需要通信双方都在线,所以需要先启动服务端进行监听,客户端才能获得连接,服务端代码: static void Main(string[] args) { TcpClient client = null; NetworkStream stream = null; byte[] buffer = null; string receiveString = null; IPAddress localIP = IPAddress.Parse("127.0.0.1")

  • C#基于Socket套接字的网络通信封装

    本文为大家分享了C#基于Socket套接字的网络通信封装代码,供大家参考,具体内容如下 摘要 之所以要进行Socket套接字通信库封装,主要是直接使用套接字进行网络通信编程相对复杂,特别对于初学者而言.实际上微软从.net 2.0开始已经提供了TCP.UDP通信高级封装类如下: TcpListener TcpClient UdpClient 微软从.net 4.0开始提供基于Task任务的异步通信接口.而直接使用socket封装库,很多socket本身的细节没办法自行控制,本文目就是提供一种so

  • Python 网络编程之TCP客户端/服务端功能示例【基于socket套接字】

    本文实例讲述了Python 网络编程之TCP客户端/服务端功能.分享给大家供大家参考,具体如下: demo.py(TCP客户端): import socket def main(): # 1. 创建tcp的套接字 tcp_socket = socket.socket(socket.AF_INET, socket.SOCK_STREAM) # 2. 链接服务器 # tcp_socket.connect(("192.168.33.11", 7890)) server_ip = input(

  • Python 网络编程之UDP发送接收数据功能示例【基于socket套接字】

    本文实例讲述了Python 网络编程之UDP发送接收数据功能.分享给大家供大家参考,具体如下: demo.py(UDP发送数据): import socket # 导入socket模块 def main(): # 创建一个udp套接字 udp_socket = socket.socket(socket.AF_INET, socket.SOCK_DGRAM) # 绑定本机ip和端口号 (发送数据时,如果不绑定,系统会随机分配端口号.接收数据时,一般需要手动绑定ip和端口) udp_socket.b

  • python socket网络编程步骤详解(socket套接字使用)

    一.套接字套接字是为特定网络协议(例如TCP/IP,ICMP/IP,UDP/IP等)套件对上的网络应用程序提供者提供当前可移植标准的对象.它们允许程序接受并进行连接,如发送和接受数据.为了建立通信通道,网络通信的每个端点拥有一个套接字对象极为重要.套接字为BSD UNIX系统核心的一部分,而且他们也被许多其他类似UNIX的操作系统包括Linux所采纳.许多非BSD UNIX系统(如ms-dos,windows,os/2,mac os及大部分主机环境)都以库形式提供对套接字的支持.三种最流行的套接

  • python基础之Socket套接字详解

    前言 Python语言提供了Socket套接字来实现网络通信. Python的应用程序通常通过Socket"套接字"向网络发出请求或者应答网络请求,使主机间或者一台计算机上的进程间可以通讯. 服务器和客户端的源代码 服务器端 #coding=utf-8 #创建TCP服务器 import socket import time from time import ctime HOST = '127.0.0.1' PORT = 8080 BUFSIZE=1024 sock = socket.s

  • python粘包问题及socket套接字编程详解

    粘包问题 TCP协议在传输过程中会出现数据粘包问题 讲一下TCP和UDP的区别,都是传数据的协议,没有好坏之说,只是不同的应用需求可能会更好选择哪一个协议 TCP:适合传输数量大 ,需要建立连接,会出现粘包问题,粘包问题可以解决,确定传入的长度,接收同样长度就可以保证一次性传输完 UDP: 适合传输数据量小,没有粘包,不需要连接,一次性传输,下一次就是新的数据,弊端就是数据丢失,不安全 QQ是用什么协议呢?按理应该可以用UDP协议,但是实际用的是TCP协议,这是历史遗留问题,可还记得我们输入QQ

  • Python socket 套接字实现通信详解

    首先:我们介绍一下socket什么是socket: 1. socket 在操作系统中它是处于应用层与传输层的抽象层,它是一组操作起来非常简单的接口(接收数据的),此接口接受数据之后交个操作系统 那么为什么?直接给操作系统不是更方便吗?那么你就想错了 因为操作系统的接口远比我们想象的要丑陋复杂,使用操作系统交换数据,非诚繁琐,,开发者们只能想办法让一个中间人和他们打交道,来简单的实现数据交换,那么就是socket套接字.它的作用就是:与操作系统之间数据交换将这些繁琐的操作,进行高度化封装,和简化,

  • Python socket套接字实现C/S模式远程命令执行功能案例

    本文实例讲述了Python socket套接字实现C/S模式远程命令执行功能.分享给大家供大家参考,具体如下: 一. 前言 要求: 使用python的socket套接字编写服务器/客户机模式的远程命令执行脚本. serverCmd.py 远程机器上用来执行客户端发送命令的脚本 clientCmd.py 本地机器上,向远程服务器发送命令的脚本 servers.txt  本地机器上,存放所有的远程服务器IP地址文件(仅支持第一个IP) 发送:cmd [command]形式消息,让远程主机执行命令(本

  • C#之Socket(套接字)通信

    一.socket是什么 Socket是应用层与TCP/IP协议族通信的中间软件抽象层,它是一组接口.在设计模式中,Socket其实就是一个门面模式,它把复杂的TCP/IP协议族隐藏在Socket接口后面,对用户来说,一组简单的接口就是全部,让Socket去组织数据,以符合指定的协议.所以,我们无需深入理解tcp/udp协议,socket已经为我们封装好了,我们只需要遵循socket的规定去编程,写出的程序自然就是遵循tcp/udp标准的. 二.套接字的工作流程 先从服务器端说起.服务器端先初始化

  • 通过实例解析Socket套接字通信原理

    一.Socket是什么 Socket 的中文翻译过来就是"套接字".套接字是什么,我们先来看看它的英文含义:插座. Socket 就像一个电话插座,负责连通两端的电话,进行点对点通信,让电话可以进行通信,端口就像插座上的孔,端口不能同时被其他进程占用.而我们建立连接就像把插头插在这个插座上,创建一个 Socket 实例开始监听后,这个电话插座就时刻监听着消息的传入,谁拨通我这个"IP 地址和端口",我就接通谁. 实际上,Socket 是在应用层和传输层之间的一个抽象

随机推荐