在beginreceive回调中出错后调用beginaccept?

时间:2017-09-27 11:34:17

标签: c# sockets

我有一个Windows服务C#4.0套接字程序从一块硬件接收连接,然后接收消息并发回一个确认

如果我在开始接收回调中失败,我发现除非我再次调用beginaccept,否则我无法接受另一个接受回调。这是可接受的错误处理吗?

不确定我是否会耗尽资源

在我的代码中搜索BeginAccept。感谢。

using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
using System.Net.Sockets;
using System.Net;
using System.Data;
using System.Threading;

namespace Company.BusinessLogic
{
    public class VconnReceive : abstractReceiveClass
    {
    private static readonly log4net.ILog log = log4net.LogManager.GetLogger(System.Reflection.MethodBase.GetCurrentMethod().DeclaringType);
    private InfoSocket infoSocket;

    public override void StartListening(ConnectionsManager.ConnectionConfig configReceive)
    {
        // Data buffer for incoming data.  
        try
        {
            // Establish the local endpoint for the socket.  
        // The DNS name of the computer  
        //IPHostEntry ipHostInfo = Dns.Resolve(Dns.GetHostName());
        IPAddress ipAddress = IPAddress.Parse(configReceive.connectionIP);//ipHostInfo.AddressList[0];
        IPEndPoint localEndPoint = new IPEndPoint(ipAddress, Convert.ToInt32(configReceive.Port));

        // Create a TCP/IP socket.  
        infoSocket = new InfoSocket(new Socket(AddressFamily.InterNetwork,
                        SocketType.Stream, ProtocolType.Tcp), configReceive);
        // Bind the socket to the local endpoint and listen for incoming connections.  
        //available for outside, specifically to close if shutdown
        configReceive.AcceptSocket = infoSocket.socket;

        infoSocket.socket.Bind(localEndPoint);
        infoSocket.socket.Listen(1000);

        // Start an asynchronous socket to listen for connections.  
        //Console.WriteLine("Waiting for a connection...");
        infoSocket.socket.BeginAccept(new AsyncCallback(AcceptCallback), infoSocket);
        }
        catch (Exception e)
        {
        string strErrorMsg =
            "\r\n--------------------------------------------\r\n" +
            "\r\nError in socket startlistening ConfigReceive Connection Name\r\n" + configReceive.ConnectionName + "\r\n";
        log.Error(strErrorMsg, e);
        }

    }

    public void AcceptCallback(IAsyncResult ar)
    {
        InfoSocket infoSocket = null;
        Socket handler = null;


        log.Info("In AcceptCallback");

        try
        {
        try
        {
            // Get the socket that handles the client request.  
            infoSocket = (InfoSocket)ar.AsyncState;
            log.Info("In AcceptCallback, got socket, config connect-" + infoSocket.config.ConnectionName);
        }
        catch (Exception e1)
        {
            string strErrorMsg =
                "\r\n--------------------------------------------\r\n" +
                "\r\nError in socket accept callback getting socket!\r\n" +
                "\r\nConnection Name not known.\r\n";
            log.Error(strErrorMsg, e1);
        }


        // Create the state object.  
        StateObject state = new StateObject();
        state.workSocket = handler;
        state.config = infoSocket.config;

        IAsyncResult result = handler.BeginReceive(state.buffer, 0, StateObject.BufferSize, 0,
            new AsyncCallback(ReadCallback), state);

        log.Info("Leaving AcceptCallback, config connect-" + infoSocket.config.ConnectionName);
        }
        catch (Exception e)
        {
        try
        {
            string strErrorMsg =
                "\r\n--------------------------------------------\r\n" +
                "\r\nError2 in socket accept callback!  Config Connection Name not known\r\n";
            log.Error(strErrorMsg, e);
        }
        finally
        {
            try
            { 
            //Do I call beginaccept again?
            infoSocket.socket.BeginAccept(new AsyncCallback(AcceptCallback), infoSocket);
            //close the socket
            if (handler != null)
            {
                try
                {
                handler.Shutdown(SocketShutdown.Both);
                }
                catch (Exception e1)
                {
                log.Info(e1);
                }
            }
            if (handler != null)
            {
                try
                {
                handler.Close();
                }
                catch (Exception e1)
                {
                log.Info(e1);
                }
            }
            }
            catch(Exception e3)
            {
            try
            {
                string strErrorMsg2 =
                "\r\n--------------------------------------------\r\n" +
                "\r\nError in socket accept callback calling beginaccept!  Interface cannot accept connections!\r\n";

                log.Error(strErrorMsg2, e3);
            }
            catch
            {
            }
            }
        }
         }

         return;
    }

    public void ReadCallback(IAsyncResult ar)
    {
        Socket handler = null;
        StateObject state = null;
        try
        {
        String content = String.Empty;

        // Retrieve the state object and the handler socket  
        // from the asynchronous state object.  
        state = (StateObject)ar.AsyncState;

        handler = state.workSocket;

        // Read data from the client socket.   
        int bytesRead = handler.EndReceive(ar);


        if (bytesRead > 0)
        {
            // There  might be more data, so store the data received so far.  
            //first check for header only
            if ((bytesRead == 1) && state.buffer[0] == '\v')
            {
            if (ConnectionsManager.ConnectionConfig.StopCheck(Runnable.StopCheckCaller.Socket))
                return;

            state.buffer = new byte[StateObject.BufferSize];
            handler.BeginReceive(state.buffer, 0, StateObject.BufferSize, 0,
                        new AsyncCallback(ReadCallback), state);
            return;
            }

            state.sb.Append(Encoding.ASCII.GetString(
            state.buffer, 0, bytesRead));

            //debug purposes
            StringBuilder v1 = new StringBuilder();
            v1.Append(Encoding.ASCII.GetString(
            state.buffer, 0, bytesRead));
            //Check for end of file
            string vNewBufferObtained = v1.ToString();
            // Check for end-of-file tag. If it is not there, read   
            // more data.  
            content = state.sb.ToString();

            //We're going to split full buffer
            //into individual messages
            string t = String.Copy(content);

            //string[] msgs = Regex.Split(t, "\u001c");//\r\u001c\r\v");
            string[] msgs = t.Split('\u001c');//\r\u001c\r\v");
            bool bCompleteEnd = false;

            //test for partial message, have to exit to get the rest
            //if (msgs[msgs.Count() - 1].Substring(msgs[msgs.Count() - 1].Length - 2, 2) == "\x1C\x0D")
            //the actual check for end of transmission
            if (vNewBufferObtained.Substring(vNewBufferObtained.Length - 2, 2) == "\x1C\x0D")
            bCompleteEnd = true;

            //process the individual messages
            for (int v = 0; v < msgs.Count(); v++)
            {
            //if we're on the last message and it's not complete
            //get the rest by breaking out of here and doing
            //another receive
            if ((v == (msgs.Count() - 1)) && !bCompleteEnd)
            {
                state.buffer = new byte[StateObject.BufferSize];
                break;
            }//last message check for nothing there and if so 
             //break out of here for another receive
            else if ((msgs[v].Length == 0) || (msgs[v] == "\r"))//last record null string or cr
            {
                state.buffer = new byte[StateObject.BufferSize];
                state.sb.Clear();
                break;
            }
            else
            {   //trim any trailing stuff
                msgs[v] = msgs[v].Trim();// new Char[] { '\r', '\v' });
            }

            InfoSocket infoSocketSend = new InfoSocket(handler, state.config);

            Send(infoSocketSend, msgs[v]);
            }

            state.sb.Clear();
            //if we don't have a complete message put what we have in
            //the buffer to concatenate the next time
            if (!bCompleteEnd)
            state.sb.Append(msgs[msgs.Count() - 1]);

            //Set up for next receive
            handler.BeginReceive(state.buffer, 0, StateObject.BufferSize, 0,
            new AsyncCallback(ReadCallback), state);

        }
        else
        {
            //we received zero bytes.  something's wrong. 
            //set up to accept another connection
            //and close the socket.

             //Do I call beginaccept again????
            infoSocket.socket.BeginAccept(new AsyncCallback(AcceptCallback),
                            infoSocket);
            //close the socket
            if (handler != null)
            {
            try
            {
                handler.Shutdown(SocketShutdown.Both);
            }
            catch (Exception e1)
            {
                log.Info(e1);
            }
            }
            if (handler != null)
            {
            try
            {
                handler.Close();
            }
            catch (Exception e1)
            {
                log.Info(e1);
            }
            }
        }
        }
        catch (Exception e)
        {
        try
        {
            try
            {
            log.Error("error", e);
            }
            catch
            {
            string strErrorMsg =
                    "inner error";
            log.Error(strErrorMsg, e);
            }

        //Do I call beginaccept again?
            infoSocket.socket.BeginAccept(new AsyncCallback(AcceptCallback),
                infoSocket);

        }
        catch (Exception e2)
        {
            string strErrorMsg =
            "\r\n--------------------------------------------\r\n" +
            "\r\nE2 Error in socket read callback!  Interface cannot accept connections!\r\n";

            log.Error(strErrorMsg, e2);
        }

        if (handler != null)
        {
            try
            {
            handler.Shutdown(SocketShutdown.Both);
            }
            catch (Exception e1)
            {
            log.Info(e1);
            }
        }
        if (handler != null)
        {
            try
            {
            handler.Close();
            }
            catch (Exception e1)
            {
            log.Info(e1);
            }
        }
        }
    }

    private void Send(InfoSocket infoSocket, String data)
    {
        string sProcedure;
        string[] fields = null;

        try
        {
        string strMessage = "test";

        byte[] byteData = Encoding.ASCII.GetBytes(strMessage);

        // Begin sending the ack or nak data to the remote device.  
        infoSocket.socket.BeginSend(byteData, 0, byteData.Length, 0,
            new AsyncCallback(SendCallback), infoSocket);
        }
        catch (Exception e)
        {
           log.Error("Inner error", e1);
        }
    }

    private void SendCallback(IAsyncResult ar)
    {
        InfoSocket infoSocket = null;
        try
        {
        // Retrieve the socket from the state object.  
        infoSocket = (InfoSocket)ar.AsyncState;

        // Complete sending the data to the remote device.  
        int bytesSent = infoSocket.socket.EndSend(ar);


        }
        catch (Exception e)
        {
        //error handling
        }
    }
    }
}

0 个答案:

没有答案