zoukankan      html  css  js  c++  java
  • dotnet socket

    服务端操作

    //1、创建IPE
    int port = 6000;
    string host = "127.0.0.1";
    IPAddress ip = IPAddress.Parse(host);
    IPEndPoint ipe = new IPEndPoint(ip, port);
    
    //2、创建socket
    Socket sSocket = new Socket(AddressFamily.InterNetwork, SocketType.Stream, ProtocolType.Tcp);
    //3、绑定端口与ip
    //如果要指定本地 IP 地址和端口号,请在调用 Listen 方法之前调用 Bind 方法
    sSocket.Bind(ipe);
    //4、监听,如果希望基础服务提供商为你分配一个可用端口,请使用端口号零
    //如果使用面向连接的协议(例如 TCP),则服务器可以使用 Listen 方法侦听连接
    sSocket.Listen(0);
    
    Console.WriteLine("监听已经打开,请等待");
    
    //5、获取通信socket
    //receive message, Accept 方法处理任何传入连接请求,并返回可用于与远程主机通信的 Socket
    Socket serverSocket = sSocket.Accept();
    
    Console.WriteLine("连接已经建立");
    string recStr = "";
    byte[] recByte = new byte[4096];
    //6、接收数据。若要传递数据,请调用 Send 或 Receive 方法
    int bytes = serverSocket.Receive(recByte, recByte.Length, 0);
    recStr += Encoding.ASCII.GetString(recByte, 0, bytes);
    
    //send message
    Console.WriteLine("服务器端获得信息:{0}", recStr);
    string sendStr = "send to client :hello";
    byte[] sendByte = Encoding.ASCII.GetBytes(sendStr);
    //7、发送数据
    serverSocket.Send(sendByte, sendByte.Length, 0);
    serverSocket.Close();
    sSocket.Close();
    

    client

    //1、创建ipe
    int port = 6000;
    string host = "127.0.0.1";//服务器端ip地址
    IPAddress ip = IPAddress.Parse(host);
    IPEndPoint ipe = new IPEndPoint(ip, port);
    
    //2、创建socket
    Socket clientSocket = new Socket(AddressFamily.InterNetwork, SocketType.Stream, ProtocolType.Tcp);
    //3、connect
    clientSocket.Connect(ipe);
    
    //4、send message
    string sendStr = "send to server : hello,ni hao";
    byte[] sendBytes = Encoding.ASCII.GetBytes(sendStr);
    clientSocket.Send(sendBytes);
    
    //5、receive message
    string recStr = "";
    byte[] recBytes = new byte[4096];
    int bytes = clientSocket.Receive(recBytes, recBytes.Length, 0);
    recStr += Encoding.ASCII.GetString(recBytes, 0, bytes);
    Console.WriteLine(recStr);
    
    clientSocket.Close();
    

    下面的代码实现异步:

    using System;
    using System.Collections.Generic;
    using System.Net;
    using System.Net.Sockets;
    using System.Text;
    using System.Threading;
    using System.Threading.Tasks;
    
    // 客户端请求状态信息保存在这里
    public class StateObject
    {
        // Client socket. 
        // 客户端的socket
        public Socket workSocket = null;
        // Size of receive buffer.  
        public const int BufferSize = 1024;
        // Receive buffer.  
        public byte[] buffer = new byte[BufferSize];
        // Received data string.  
        public StringBuilder sb = new StringBuilder();
    }
    
    public class AsynchronousSocketListener
    {
    
        public static List<Socket> ClientSockets = new List<Socket>();
    
        // 线程信号  
        public static ManualResetEvent allDone = new ManualResetEvent(false);
        
        /// <summary>
        /// 构造函数
        /// </summary>
        public AsynchronousSocketListener()
        {
        }
    
        /// <summary>
        /// 开始监听
        /// </summary>
        public static void StartListening()
        {
            // Establish the local endpoint for the socket.  
            // The DNS name of the computer  
            // running the listener is "host.contoso.com".  
            IPHostEntry ipHostInfo = Dns.GetHostEntry(Dns.GetHostName());
            IPAddress ipAddress = ipHostInfo.AddressList[3];
            IPEndPoint localEndPoint = new IPEndPoint(ipAddress, 11000);
    
            // Create a TCP/IP socket.  
            Socket listener = new Socket(ipAddress.AddressFamily,
                SocketType.Stream, ProtocolType.Tcp);
    
            // Bind the socket to the local endpoint and listen for incoming connections.  
            try
            {
                listener.Bind(localEndPoint);
                listener.Listen(100);
                Task.Run(()=> {
                    while (true)
                    {
                        // Set the event to nonsignaled state.  
                        allDone.Reset();
    
                        // Start an asynchronous socket to listen for connections. 
                        // AsyncCallback 让回调函数在单独的线程中执行
                        Console.WriteLine("Waiting for a connection...");
                        // 处理传入的请求,这个只有在客户端发起握手的时候才调用
                        listener.BeginAccept(
                            new AsyncCallback(AcceptCallback),
                            listener);
    
                        // Wait until a connection is made before continuing.                  
                        allDone.WaitOne();
                    }
                });
    
                while (true)
                {
    
                    for (int i = 0; i < ClientSockets.Count; i++)
                    {
                        try
                        {
                            Send(ClientSockets[i], "hello i am server
    ");
                        }
                        catch (Exception)
                        {
                            ClientSockets.RemoveAt(i);
                        }
                    }
                    Thread.Sleep(100);
                }
    
    
            }
            catch (Exception e)
            {
                Console.WriteLine(e.ToString());
            }
    
            Console.WriteLine("
    Press ENTER to continue...");
            Console.Read();
    
        }
    
        /// <summary>
        /// 监听回调
        /// </summary>
        /// <param name="ar"></param>
        public static void AcceptCallback(IAsyncResult ar)
        {
            // 标记主线程继续执行  
            allDone.Set();
    
            // 获取socket来处理client请求  
            Socket listener = (Socket)ar.AsyncState;
            Socket handler = listener.EndAccept(ar);     
    
            // 创建数据对象(储存接收数据)
            StateObject state = new StateObject();
            state.workSocket = handler;
            //存储请求来的socket,方便从server发送到client
            ClientSockets.Add(handler);
            Console.WriteLine(ClientSockets.Count);
            // 处理传递进来的数据
            handler.BeginReceive(state.buffer, 0, StateObject.BufferSize, 0,
                new AsyncCallback(ReadCallback), state);
        }
    
        /// <summary>
        /// 读取客户端请求数据回调
        /// </summary>
        /// <param name="ar"></param>
        public static void ReadCallback(IAsyncResult ar)
        {
            String content = String.Empty;
    
            // Retrieve the state object and the handler socket  
            // from the asynchronous state object.  
            // 在read回调函数中调用 IAsyncResult(ar) 的 AsyncState 方法,以获取传递给 BeginReceive 方法的状态对象
            // 此时就已经获取到客户端请求的数据,存储在state.buffer中,如果此时还有数据进来也不会填充state的buffer,而是等待下一次回调被调用
            StateObject state = (StateObject)ar.AsyncState;
            // 从此状态对象中提取接收 Socket
            Socket handler = state.workSocket;
    
    
            // Read data from the client socket.
            // 获取 Client Socket后,可以调用 EndReceive 方法成功完成(关闭) BeginReceive 方法中启动的异步读取操作,并返回所读取的字节数      
            int bytesRead = handler.EndReceive(ar);
    
            if (bytesRead > 0)
            {
                // There  might be more data, so store the data received so far.
                // 可能会有很多数据要接收,暂存当前已经接收到的数据,StateObject.buffer在ar.AsyncState的时候就已经被填充(实测)
                state.sb.Clear();
                state.sb.Append(Encoding.ASCII.GetString(state.buffer, 0, bytesRead));
    
                // Check for end-of-file tag. If it is not there, read
                // more data. 
                // 检查end-of-file,如果没哟检测到就再继续读。
                content = state.sb.ToString();
                Console.WriteLine(content);
                /*
                if (content.IndexOf("<EOF>") > -1)
                {
                    // All the data has been read from the
                    // client. Display it on the console.  
                    Console.WriteLine("Read {0} bytes from socket. 
     Data : {1}",
                        content.Length, content);
                    // Echo the data back to the client.  
                    Send(handler, content);
                }
                else
                {
                    // Not all data received. Get more.  
                    // 没有读取到所有数据,继续读取,这里是个递归
                    handler.BeginReceive(state.buffer, 0, StateObject.BufferSize, 0,
                    new AsyncCallback(ReadCallback), state);
                }*/
                handler.BeginReceive(state.buffer, 0, StateObject.BufferSize, 0,
                    new AsyncCallback(ReadCallback), state);
            }
        }
    
        private static void Send(Socket handler, String data)
        {
            // Convert the string data to byte data using ASCII encoding.  
            // 转换string到字节数组。使用ASCII编码
            byte[] byteData = Encoding.ASCII.GetBytes(data);
    
            // Begin sending the data to the remote device. 
            // 开始发送,异步发送
            // 这里的handler是客户端client请求来的
            handler.BeginSend(byteData, 0, byteData.Length, 0,
                new AsyncCallback(SendCallback), handler);
        }
    
        /// <summary>
        /// 发送回调,发送什么如何发送在这里实现
        /// </summary>
        /// <param name="ar"></param>
        private static void SendCallback(IAsyncResult ar)
        {
            try
            {
                // Retrieve the socket from the state object
                // 获取socket ,ar.AsyncState返回的是个object类型,可以转为state也可以转为socket
                Socket handler = (Socket)ar.AsyncState;
    
                // Complete sending the data to the remote device. 
                // 在回调方法中,调用 IAsyncResult 参数的 AsyncState 方法以获取发送 Socket。 
                // 获取 Socket后,可以调用 EndSend 方法成功完成发送操作,并返回发送的字节数。
                int bytesSent = handler.EndSend(ar);
                //Console.WriteLine("Sent {0} bytes to client.", bytesSent);
    
                //handler.Shutdown(SocketShutdown.Both);
                //handler.Close();
            }
            catch (Exception e)
            {
                Console.WriteLine(e.ToString());
            }
        }
    
        public static int Main(String[] args)
        {
            StartListening();
            return 0;
        }
    }
    
  • 相关阅读:
    【JS】 Javascript 入门
    【CSS】 CSS的一些应用实例和参考
    【CSS】 CSS 定位
    【泛泛】 不知道怎么分类的豆知识
    【CSS】 CSS基础知识 属性和选择
    【HTML】 HTML基础知识 表单
    【HTML】 HTML基础知识 一些标签
    【Linux】 文本比较工具 diff和cmp
    php -- or 的用法
    php -- 检查是否存在
  • 原文地址:https://www.cnblogs.com/feipeng8848/p/13218052.html
Copyright © 2011-2022 走看看