我如何重用套接字? [英] How do I reuse a socket?

查看:93
本文介绍了我如何重用套接字?的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述





这几乎与ASync客户端/服务器TCPIP应用程序的Microsoft示例相同,我所做的唯一更改是支持IPV6和再次收听下一个连接。这是我遇到问题的地方,再次听。我试过处理插座,但这似乎没有帮助。我不断收到此错误:



5/3/2014 7:45:32 PM,每个套接字地址(协议/网络地址/端口)只有一种用法是通常允许,在System.Net.Sockets.Socket.DoBind(EndPoint endPointSnapshot,SocketAddress socketAddress)

在System.Net.Sockets.Socket.Bind(EndPoint localEP)

在CInstaller.CInstall.WaitForConnection()CInstall.cs:第163行



我在ReadCallback结束时启动一个新线程,等待另一个连接。我已经指出了第163行的位置<<<<问题专线



非常感谢任何帮助...



谢谢,

Glenn





Hi,

This is almost identical to the Microsoft example of an ASync Client/Server TCPIP application, the only changes I've made is to support IPV6 and to listen again for the next connection. This is where I've come into a problem, listening again. I've tried disposing of the socket but that doesn't seem to help. I continuously receive this error:

5/3/2014 7:45:32 PM, Only one usage of each socket address (protocol/network address/port) is normally permitted, at System.Net.Sockets.Socket.DoBind(EndPoint endPointSnapshot, SocketAddress socketAddress)
at System.Net.Sockets.Socket.Bind(EndPoint localEP)
at CInstaller.CInstall.WaitForConnection() CInstall.cs:line 163

I start a new thread at the end of ReadCallback to wait for another connection. I've indicated where line 163 is below with <<<< Problem Line

Any help is greatly appreciated...

Thanks,
Glenn


private void WaitForConnection()
        {
            string work;

            Int32 port;
            byte[] bytes = new Byte[1024];

            try
            {
                if (string.IsNullOrEmpty(GetSet.TCPIPPort))
                {
                    Thread.Sleep(200);
                    if (string.IsNullOrEmpty(GetSet.TCPIPPort))
                    {
                        if (!EventLog.SourceExists(GetSet.ProductName))
                            EventLog.CreateEventSource(GetSet.ProductName, "Application");

                        eventLogInstaller.Source = GetSet.ProductName;
                        eventLogInstaller.Log = "Application";
                        work = string.Format("{0}, {1}:  ", DateTime.Now, "TCPIP Port not set, service terminating.");
                        eventLogInstaller.WriteEntry(work);
                        this.Stop();
                    }
                }

                port = Convert.ToInt32(GetSet.TCPIPPort);

                // Establish the local endpoint for the socket.
                // The DNS name of the computer
                // running the listener is 
                IPHostEntry ipHostInfo = Dns.GetHostEntry(Dns.GetHostName());
                IPAddress ipAddress = ipHostInfo.AddressList[0];
                IPEndPoint localEndPoint = new IPEndPoint(ipAddress, port);

                // Create a TCP/IP socket.
                Socket listener = new Socket(ipAddress.AddressFamily,
                    SocketType.Stream, ProtocolType.Tcp);

                work = string.Format("{0} {1} - Waiting for connection on IPAddress: {2}, port {3}", 
                                    GetSet.ProductName, DateTime.Now, ipAddress, GetSet.TCPIPPort);
                Trace.WriteLine(work);

                // Bind the socket to the local endpoint and listen for incoming connections.
                listener.Bind(localEndPoint); // <<<<< Problem line
                listener.Listen(100);

                while (true)
                {
                    // Set the event to nonsignaled state.
                    allDone.Reset();

                    // Start an asynchronous socket to listen for connections.
                    listener.BeginAccept(new AsyncCallback(AcceptCallback), listener);

                    // Wait until a connection is made before continuing.
                    allDone.WaitOne();
                    break;
                }
            }

            catch (Exception ex)
            {
                if (!EventLog.SourceExists(GetSet.ProductName))
                    EventLog.CreateEventSource(GetSet.ProductName, "Application");

                eventLogInstaller.Source = GetSet.ProductName;
                eventLogInstaller.Log = "Application";

                work = string.Format("{0}, {1}, {2}", DateTime.Now, ex.Message, ex.StackTrace);
                eventLogInstaller.WriteEntry(work);
                Trace.WriteLine(work);
                return;
            }
        }

        public void AcceptCallback(IAsyncResult ar)
        {
            try
            {
                work = string.Format("{0} {1} - AcceptCallback Start",
                                    GetSet.ProductName, DateTime.Now);
                Trace.WriteLine(work);

                // Signal the main thread to continue.
                allDone.Set();

                // Get the socket that handles the client request.
                Socket listener = (Socket)ar.AsyncState;
                Socket handler = listener.EndAccept(ar);

                // Create the state object.
                StateObject state = new StateObject();
                state.workSocket = handler;
                handler.BeginReceive(state.buffer, 0, StateObject.BufferSize, 0,
                    new AsyncCallback(ReadCallback), state);

                work = string.Format("{0} {1} - AcceptCallback End",
                                    GetSet.ProductName, DateTime.Now);
                Trace.WriteLine(work);
            }

            catch (Exception ex)
            {
                if (!EventLog.SourceExists(GetSet.ProductName))
                    EventLog.CreateEventSource(GetSet.ProductName, "Application");

                eventLogInstaller.Source = GetSet.ProductName;
                eventLogInstaller.Log = "Application";

                work = string.Format("{0}, {1}, {2}", DateTime.Now, ex.Message, ex.StackTrace);
                eventLogInstaller.WriteEntry(work);
                Trace.WriteLine(work);
                return;
            }
        }

        public void ReadCallback(IAsyncResult ar)
        {
            String content = String.Empty;
            Thread threadProcessMessage;

            try
            {
                work = string.Format("{0} {1} - ReadCallback Start",
                                    GetSet.ProductName, DateTime.Now);
                Trace.WriteLine(work);

                // Retrieve the state object and the handler socket
                // from the asynchronous state object.
                StateObject state = (StateObject)ar.AsyncState;
                Socket 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.
                    state.sb.Append(Encoding.ASCII.GetString(state.buffer, 0, bytesRead));

                    // Check for end-of-file tag. If it is not there, read 
                    // more data.
                    content = state.sb.ToString();
                    if (content.IndexOf("<EOF>") > -1)
                    {
                        GetSet.Message = content;
                        // All the data has been read from the client, write it to trace file
                        mreInstallThread.Reset();
                        threadProcessMessage = new Thread(new ThreadStart(ProcessMessage));
                        threadProcessMessage.Start();
                        
                        work = string.Format("Read {0} bytes from socket. \n Data : {1}", content.Length, content);
                        Trace.WriteLine(work);

                        // Echo the data back to the client.
                        Send(handler, content);
                        mreInstallThread.WaitOne(375);
                    }
                    else
                    {
                        // Not all data received. Get more.
                        handler.BeginReceive(state.buffer, 0, StateObject.BufferSize, 0,
                                             new AsyncCallback(ReadCallback), state);
                    }
                }

                Thread.Sleep(1000);

                GetSet.threadInstallComm = new Thread(new ThreadStart(WaitForConnection));
                GetSet.threadInstallComm.Start();

                work = string.Format("{0} {1} - ReadCallback End",
                                    GetSet.ProductName, DateTime.Now);
                Trace.WriteLine(work);
            }

            catch (Exception ex)
            {
                if (!EventLog.SourceExists(GetSet.ProductName))
                    EventLog.CreateEventSource(GetSet.ProductName, "Application");

                eventLogInstaller.Source = GetSet.ProductName;
                eventLogInstaller.Log = "Application";

                work = string.Format("{0}, {1}, {2}", DateTime.Now, ex.Message, ex.StackTrace);
                eventLogInstaller.WriteEntry(work);
                Trace.WriteLine(work);
                return;
            }
        }

        private void Send(Socket handler, String data)
        {
            try
            {
                work = string.Format("{0} {1} - Send Start",
                                    GetSet.ProductName, DateTime.Now);
                Trace.WriteLine(work);

                // Convert the string data to byte data using ASCII encoding.
                byte[] byteData = Encoding.ASCII.GetBytes(data);

                // Begin sending the data to the remote device.
                handler.BeginSend(byteData, 0, byteData.Length, 0,
                    new AsyncCallback(SendCallback), handler);

                work = string.Format("{0} {1} - Send End",
                                    GetSet.ProductName, DateTime.Now);
                Trace.WriteLine(work);
            }

            catch (Exception ex)
            {
                if (!EventLog.SourceExists(GetSet.ProductName))
                    EventLog.CreateEventSource(GetSet.ProductName, "Application");

                eventLogInstaller.Source = GetSet.ProductName;
                eventLogInstaller.Log = "Application";

                work = string.Format("{0}, {1}, {2}", DateTime.Now, ex.Message, ex.StackTrace);
                eventLogInstaller.WriteEntry(work);
                Trace.WriteLine(work);
                return;
            }
        }

        private void SendCallback(IAsyncResult ar)
        {
            try
            {
                work = string.Format("{0} {1} - SendCallback Start",
                                    GetSet.ProductName, DateTime.Now);
                Trace.WriteLine(work);
                // Retrieve the socket from the state object.
                Socket handler = (Socket)ar.AsyncState;

                // Complete sending the data to the remote device.
                int bytesSent = handler.EndSend(ar);
                work = string.Format("Sent {0} bytes to client.", bytesSent);
                Trace.WriteLine(work);

                handler.Shutdown(SocketShutdown.Both);
                handler.Close();

                work = string.Format("{0} {1} - SendCallback End",
                                    GetSet.ProductName, DateTime.Now);
                Trace.WriteLine(work);
            }

            catch (Exception ex)
            {
                if (!EventLog.SourceExists(GetSet.ProductName))
                    EventLog.CreateEventSource(GetSet.ProductName, "Application");

                eventLogInstaller.Source = GetSet.ProductName;
                eventLogInstaller.Log = "Application";

                work = string.Format("{0}, {1}, {2}", DateTime.Now, ex.Message, ex.StackTrace);
                eventLogInstaller.WriteEntry(work);
                Trace.WriteLine(work);
                return;
            }
        }

推荐答案

在WaitForConnection方法中删除while循环中的break后,不再需要再次调用WaitForConnection方法。这解决了这个问题。
After removing the "break" in the while loop in the WaitForConnection method there is no longer a need to call the WaitForConnection method again. This resolved the problem.


这篇关于我如何重用套接字?的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!

查看全文
登录 关闭
扫码关注1秒登录
发送“验证码”获取 | 15天全站免登陆