C# socket通信TCP和UDP方式

这里写一篇文章来和大家请教一下,关于socket通信的方式

这里我也是通过网络的其他地方整理的代码,来实现自己的功能

但是我发现一个问题,就是如此采用UDP方式,必须先向服务端发送一个数据才能接受到来自服务器定时不断发出的数据。不知道怎么解决。小弟对UDP方式理解的不够深入,求大神指导呢

这里贴出源码

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


namespace SocketHelp
{
    public delegate void ReadDataEvent(byte[] Bytes, int size);
    
    #region TCP协议


    #region ClientTCP
    public class ClientTCP
    {
        private Socket client;
        public byte[] oubytes;
        //public static PrintMsg _PrintMsg;
        public ReadDataEvent ReadData;
        public ClientTCP()
        {
            oubytes =new byte[1024];
        }
        public bool StartClient(string IP, int port)
        {
            try
            {
                client = new Socket(AddressFamily.InterNetwork, SocketType.Stream, ProtocolType.Tcp);
                client.BeginConnect(IP, port, new AsyncCallback(ConnectTarget), client);
                // 接收输入并发消息  
                //bool send = false;
                //while (true)
                //{
                //    showMsg("ME: " + DateTimeOffset.Now.ToString("G"));
                //    send = SendMsg;
                //    inbytes = Encoding.UTF8.GetBytes(Msg);
                //    client.BeginSend(inbytes, 0, inbytes.Length, SocketFlags.None, new AsyncCallback(SendTarget), client);
                //}
                //client.Close();  
                return true;
            }
            catch (Exception ex)
            {
                Method.writeLog(ex.Message.ToString());
                return false;
            }
        }
        public bool SendData(byte[] Bytes)
        {
            try
            {
                client.BeginSend(Bytes, 0, Bytes.Length, SocketFlags.None, new AsyncCallback(SendTarget), client);
                return true;
            }
            catch (Exception ex)
            {
                Method.writeLog(ex.Message.ToString());
                return false;
            }
        }
        private void ConnectTarget(IAsyncResult res)
        {
            Method.writeLog("已建立连接");
            Socket sever = (Socket)res.AsyncState;
            sever.EndConnect(res);
            sever.BeginReceive(oubytes, 0, oubytes.Length, SocketFlags.None, ReceiveData, sever);
        }


        private void SendTarget(IAsyncResult res)
        {
            //Socket client = (Socket)res.AsyncState;
            //int size = client.EndSend(res);
        }


        private void ReceiveData(IAsyncResult res)
        {
            try
            {
                Socket sever = (Socket)res.AsyncState;
                int size = sever.EndReceive(res);
                if (ReadData != null)
                {
                    //解析数据
                    ReadData(oubytes, size);
                }
                // 继续等待输入  
                sever.BeginReceive(oubytes, 0, oubytes.Length, SocketFlags.None, new AsyncCallback(ReceiveData), sever);
            }
            catch (Exception ex)
            {
                Method.writeLog(ex.Message.ToString());
            }
        }
    }
    #endregion


    #region ServiceTCP
    public class ServiceTCP
    {
        //public static PrintMsg _PrintMsg;
        public ReadDataEvent ReadData;
        //public static SendDataEvent SendData;
        public byte[] oubytes;
        public List<ClientInfo> clientList;
        public ServiceTCP()
        {
            clientList=new List<ClientInfo>();
            oubytes = new byte[1024];
        }
        public bool OpenService(int port)
        {
            try
            {
                IPEndPoint localEndPoint = new IPEndPoint(IPAddress.Any, port);//本机预使用的IP和端口
                Socket server = new Socket(AddressFamily.InterNetwork, SocketType.Stream, ProtocolType.Tcp);
                server.Bind(localEndPoint); // 绑定IP+端口  
                server.Listen(10); // 开始监听  


                Method.writeLog("等待连接...");
                IAsyncResult res = server.BeginAccept(new AsyncCallback(AcceptTarget), server);
                //while (SendMsg)
                //{
                //    showMsg("ME: " + DateTimeOffset.Now.ToString("G"));
                //    ClientManager.SendMsgToClientList(BroadMsg);
                //}
                //server.Close();
                return true;
            }
            catch(Exception ex)
            {
                Method.writeLog(ex.Message.ToString());
                return false;
            }


        }
        // 监听请求  
        private void AcceptTarget(IAsyncResult res)
        {
            Socket server = (Socket)res.AsyncState;
            Socket client = server.EndAccept(res);
            string address = client.RemoteEndPoint.ToString();


            clientAdd(new ClientInfo() { Socket = client, Address = address, IsOpen = true });
            Method.writeLog(address + "连接进入");
            client.BeginReceive(oubytes, 0, oubytes.Length, SocketFlags.None, new AsyncCallback(ReceiveData), client);


            SendMsgUTF8ToClient("10", address);
            // 继续监听  
            server.BeginAccept(new AsyncCallback(AcceptTarget), server);
        }
        // 接收消息  
        private void ReceiveData(IAsyncResult res)
        {
            try
            {
                Socket client = (Socket)res.AsyncState;
                int size = client.EndReceive(res);
                if (ReadData != null)
                {
                    ReadData(oubytes, size);
                }
                // 继续等待  
                client.BeginReceive(oubytes, 0, oubytes.Length, SocketFlags.None, new AsyncCallback(ReceiveData), client);
            }
            catch(Exception ex)
            {
                Method.writeLog(ex.Message.ToString());
                Method.writeLog("一个客户端断开连接");
            }
        }
        private void SendTarget(IAsyncResult res)
        {
            //Socket client = (Socket)res.AsyncState;
            //int size = client.EndSend(res);
            //client.Shutdown(SocketShutdown.Both);
            //client.Close();
        }


        #region 客户端管理
        
        public void clientAdd(ClientInfo info)
        {
            if (!clientIsExist(info.Address))
            {
                clientList.Add(info);
            }
        }
        public bool clientIsExist(string address)
        {
            return clientList.Exists(item => string.Compare(address, item.Address, true) == 0);
        }
        public void clientClose(string address)
        {
            clientList.ForEach(item =>
            {
                if (string.Compare(address, item.Address, true) == 0)
                {
                    item.IsOpen = false;
                }
            });
        }
        // 发送消息到ClientList  
        public void SendMsgUTF8ToClient(string msg, string address = null)
        {
            byte[] bt = Encoding.UTF8.GetBytes(msg);
            clientList.ForEach(item =>
            {
                if (item.IsOpen && (address == null || item.Address == address))
                {
                    item.Socket.BeginSend(bt, 0, bt.Length, SocketFlags.None, new AsyncCallback(SendTarget), item.Socket);
                }
            });
        }
        public void SendMsgToClient(byte[] bt, string address = null)
        {
            clientList.ForEach(item =>
            {
                if (item.IsOpen && (address == null || item.Address == address))
                {
                    item.Socket.BeginSend(bt, 0, bt.Length, SocketFlags.None, new AsyncCallback(SendTarget), item.Socket);
                }
            });
        }
        #endregion
    }
    //保存客户端信息
    public class ClientInfo
    {
        public Socket Socket { get; set; }
        public bool IsOpen { get; set; }
        public string Address { get; set; }
    }
    #endregion


    #endregion


    #region UDP协议


    #region ClientUDP
    public class ClientUDP
    {
        //客户端 Socket对象
        private Socket clientSocket;
        //服务器端 终点
        private EndPoint epServer;
        //数据存放
        public byte[] oubytes;
        //解析数据委托
        public  ReadDataEvent ReadData;
        public ClientUDP()
        {
            oubytes = new byte[1024];
        }
        public  bool StartClient(string IP, int port)
        {
            try
            {
                //客户端Socket对象实例化
                clientSocket = new Socket(AddressFamily.InterNetwork, SocketType.Dgram, ProtocolType.Udp);
                //设置服务器端IP地址和对应端口
                IPEndPoint server = new IPEndPoint(IPAddress.Parse(IP), port);
                //实例化服务器端 终点
                epServer = (EndPoint)server;
                clientSocket.Connect(server);
                //byte[] sendData = Encoding.UTF8.GetBytes("连接");
                //clientSocket.BeginSendTo(sendData, 0, sendData.Length, SocketFlags.None, epServer, new AsyncCallback(SendTarget), null);
                clientSocket.BeginReceiveFrom(oubytes, 0, oubytes.Length, SocketFlags.None, ref epServer, new AsyncCallback(ReceiveData), null);
                return true;
            }
            catch (Exception ex)
            {
                Method.writeLog(ex.Message.ToString());
                return false;
            }
        }
        private void ReceiveData(IAsyncResult res)
        {
            try
            {
                int size = clientSocket.EndReceive(res);
                //将接收到的数据打印出来
                if (ReadData != null)
                {
                    ReadData(oubytes, size);
                }
                //继续接受数据
                clientSocket.BeginReceiveFrom(oubytes, 0, oubytes.Length, SocketFlags.None, ref epServer, new AsyncCallback(ReceiveData), null);
            }
            catch (Exception ex)
            {
                Method.writeLog(ex.Message.ToString());
                Method.writeLog("一个客户端断开连接");
            }
        }
        public bool SendData(byte[] Bytes)
        {
            try
            {
                clientSocket.BeginSendTo(Bytes, 0, Bytes.Length, SocketFlags.None, epServer, new AsyncCallback(SendTarget), null);
                return true;
            }
            catch (Exception ex)
            {
                Method.writeLog(ex.Message.ToString());
                return false;
            }
        }
        private void SendTarget(IAsyncResult res)
        {
            clientSocket.EndSend(res);
        }
    }
    #endregion


    #region ServiceUDP
    public class ServiceUDP
    {
        //服务器端Socket对象
        private Socket serverSocket;
        //客户端 终点
        private EndPoint epSender;
        //数据存放
        public byte[] oubytes;
        //解析数据委托
        public ReadDataEvent ReadData;
        public ServiceUDP()
        {
            oubytes = new byte[1024];
        }
        public bool OpenService(int port)
        {
            try
            {
                //实例化服务器端Socket对象
                serverSocket = new Socket(AddressFamily.InterNetwork, SocketType.Dgram, ProtocolType.Udp);
                //服务器端的IP和端口,IPAddress.Any实际是:0.0.0.0,表示任意,基本上表示本机IP
                IPEndPoint server = new IPEndPoint(IPAddress.Any, 9055);
                //Socket对象跟服务器端的IP和端口绑定
                serverSocket.Bind(server);
                //客户端的IP和端口,端口 0 表示任意端口
                IPEndPoint clients = new IPEndPoint(IPAddress.Any, 0);
                //实例化客户端 终点
                epSender = (EndPoint)clients;
                //开始异步接收消息  接收后,epSender存储的是发送方的IP和端口
                serverSocket.BeginReceiveFrom(oubytes, 0, oubytes.Length, SocketFlags.None, ref epSender, new AsyncCallback(ReceiveData), epSender);
                return true;
            }
            catch (Exception ex)
            {
                Method.writeLog(ex.Message.ToString());
                return false;
            }
        }
        private void ReceiveData(IAsyncResult res)
        {
            try
            {
                //结束异步接收消息  recv 表示接收到的字符数
                int size = serverSocket.EndReceiveFrom(res, ref epSender);
                if (ReadData != null)
                {
                    ReadData(oubytes, size);
                }
                //
                byte[] Bytes = Encoding.ASCII.GetBytes("10");
                serverSocket.BeginSendTo(Bytes, 0, Bytes.Length, SocketFlags.None, epSender, new AsyncCallback(SendTarget), epSender);
                // 继续等待  
                serverSocket.BeginReceiveFrom(oubytes, 0, oubytes.Length, SocketFlags.None, ref epSender, new AsyncCallback(ReceiveData), epSender);
            }
            catch (Exception ex)
            {
                Method.writeLog(ex.Message.ToString());
                Method.writeLog("一个客户端断开连接");
            }
        }
        public bool SendData(byte[] Bytes)
        {
            try
            {
                serverSocket.BeginSendTo(Bytes, 0, Bytes.Length, SocketFlags.None, epSender, new AsyncCallback(SendTarget), epSender);
                //server.BeginSend(Bytes, 0, Bytes.Length, SocketFlags.None, new AsyncCallback(SendTarget), server);
                return true;
            }
            catch (Exception ex)
            {
                Method.writeLog(ex.Message.ToString());
                return false;
            }
        }
        private static void SendTarget(IAsyncResult res)
        {
            //Socket client = (Socket)res.AsyncState;
            //int size = client.EndSend(res);
        }
    }
    #endregion


    #endregion


    public class Method
    {
        public static string GetHostIP()   //获取本地IP
        {
            System.Net.IPHostEntry IpEntry = System.Net.Dns.GetHostEntry(System.Net.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)
                {
                    return IpEntry.AddressList[i].ToString();
                }
            }
            return "";
        }


        public static void writeLog(string messge)
        {
            string LogtxtPath = System.Windows.Forms.Application.StartupPath + "\\Socketlog.txt";
            if (!File.Exists(LogtxtPath))
            {


                FileStream txtFile = new FileStream(LogtxtPath, FileMode.Create, FileAccess.Write);//创建写入文件 
                StreamWriter sw = new StreamWriter(txtFile, System.Text.Encoding.Unicode);
                sw.WriteLine(DateTime.Now + "-" + messge);//开始写入值
                sw.Close();
                txtFile.Close();


            }
            else
            {
                FileStream txtFile = new FileStream(LogtxtPath, FileMode.Append, FileAccess.Write);
                StreamWriter sw = new StreamWriter(txtFile, System.Text.Encoding.Unicode);
                sw.WriteLine(DateTime.Now + "-" + messge);//开始写入值
                sw.Close();
                txtFile.Close();
            }
        }
    }
}

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值