zoukankan      html  css  js  c++  java
  • 【.Net】Socket小示例

    引言

         项目中用到了Socket,这里做个控制台小示例记录一下。

    Client

        客户端的Receive用了异步方法,保持长连接,可以随时发送消息和响应服务端的消息,如下

            static string ClientReceiveMessage = "";
            static byte[] receivedBytes = new byte[1024];
            static void Main(string[] args)
            {
               
                IPHostEntry ipHost = Dns.Resolve("127.0.0.1");
                IPAddress ipAddress = ipHost.AddressList[0];
                IPEndPoint ipEndPoint = new IPEndPoint(ipAddress, 2012);
    
                string sendingMessage = "Hello World Socket Test";
    
                Console.WriteLine("Creating message: Hello World Socket Test");
    
    
                Socket sender = new Socket(AddressFamily.InterNetwork,
                                       SocketType.Stream,
                                       ProtocolType.Tcp);
                sender.Connect(ipEndPoint);
              
                sender.BeginReceive(receivedBytes, 0, receivedBytes.Length, 0, ReceiveCallback, sender);
    
                while (true)
                {
                    sendingMessage = Console.ReadLine();
                    byte[] forwardMessage = Encoding.ASCII.GetBytes(sendingMessage + "[FINAL]");
                    sender.Send(forwardMessage);
                }
            }
    
            private static void ReceiveCallback(IAsyncResult ar)
            {
                Socket client = (Socket)ar.AsyncState;
    
                int totalBytesReceived = client.EndReceive(ar);
    
                if (totalBytesReceived > 0)
                {
                  
                    ClientReceiveMessage += Encoding.ASCII.GetString(receivedBytes, 0, totalBytesReceived);
                   if (ClientReceiveMessage.IndexOf("[FINAL]", StringComparison.Ordinal) > -1)
                    {
                        Console.WriteLine(ClientReceiveMessage);
                        ClientReceiveMessage = "";
                    }   
     
                    client.BeginReceive(receivedBytes, 0, receivedBytes.Length, 0, new AsyncCallback(ReceiveCallback), client);
                }
                else
                {
                    Console.WriteLine("服务端结束不再发送消息!" );
                    ClientReceiveMessage = "";
                }
    
            }

    Server

          服务端循环异步Accept,可以接收多个client消息,并且马上回复。

            static ManualResetEvent allDone = new ManualResetEvent(false);
            static void Main(string[] args)
            {
                
                Socket listener = new Socket(AddressFamily.InterNetwork,
                                             SocketType.Stream,
                                             ProtocolType.Tcp);
                listener.Bind(new IPEndPoint(IPAddress.Any, 2012));
                listener.Listen(1);
    
                while (true)
                {
                    allDone.Reset();
    listener.BeginAccept(ar => { allDone.Set(); Socket MyServer = (Socket)ar.AsyncState; Socket service = MyServer.EndAccept(ar); byte[] receivedBytes = new byte[1024]; while (true) { string receivedValue = string.Empty; int numBytes = service.Receive(receivedBytes); receivedValue += Encoding.ASCII.GetString(receivedBytes,0, numBytes); if (receivedValue.IndexOf("[FINAL]", StringComparison.Ordinal) > -1) { Console.WriteLine("Received value: {0} from " + service.RemoteEndPoint, receivedValue); string replyValue = "Message successfully received.[FINAL]"; byte[] replyMessage = Encoding.ASCII.GetBytes(replyValue); service.Send(replyMessage); } } }, listener); allDone.WaitOne(); }

    注意事项

           1.Socket的Receive方法响应次数,是以缓冲数组的大小划分。如果数组大小为1024,消息为2048,Receive将会触发两次。作为接收方无法通过Receive来确定是否已完整接收,所以要对消息另作处理,例如在消息中增加[FINAL]来确定消息已发送完毕。

           2.如果没有消息发送,接收方Receive方法会一直等待。但如果发送方调用Shutdown(SocketShutdown.Send)方法,接收方的Receive会马上返回0,所以在非来回传递消息的情况下,可以Shutdown方法来实现消息发送完毕。

           3.可以设置ReceiveTimeout的值,超时会抛出异常,然而只能作用于Receive方法,对BeginReceive无效。

           

  • 相关阅读:
    理解 RESTful:理论与最佳实践
    Shiro 性能优化:解决 Session 频繁读写问题
    单点登录的三种实现方式
    理解 Spring(二):AOP 的概念与实现原理
    理解 Spring(一):Spring 与 IoC
    MFC查内存泄漏方法
    024 --- 第28章 访问者模式
    023 --- 第27章 解释器模式
    022 --- 第26章 享元模式
    021 --- 第25章 中介者模式
  • 原文地址:https://www.cnblogs.com/caizl/p/4984633.html
Copyright © 2011-2022 走看看