c# 异步通信 两窗体互切换 同时监听两个端口 两窗体切换第4四时出现不能收发数据_.NET_编程开发_程序员俱乐部

中国优秀的程序员网站程序员频道CXYCLUB技术地图
热搜:
更多>>
 
您所在的位置: 程序员俱乐部 > 编程开发 > .NET > c# 异步通信 两窗体互切换 同时监听两个端口 两窗体切换第4四时出现不能收发数据

c# 异步通信 两窗体互切换 同时监听两个端口 两窗体切换第4四时出现不能收发数据

 2010/12/28 8:16:14  jonsion  http://jonsion.javaeye.com  我要评论(0)
  • 摘要:最近因项目需要,需要用到socket,需求是这样的,有很多台收集数据的服务器,另有三台用于监视的服务器,收集服务器向监视服务器发消息,然后监视服务器收到消息,改变相应灯的颜色。然后其中有两个窗体需要互相切换,后面决定用两个不同的端口去监听,这样就不会有数据丢失,因为发送可能同时往两个端口发消息。在这过程序中遇到很多问题,但现在很多问题都已解决了,由于任务时间紧,没有及时把遇到的问题发出来,也没有把解决方案记录下来,现在有很多都不知道怎么解决了。本人对java比较了解,对c#是门外汉,只有查资料
  • 标签:C# 数据 监听

???? 最近因项目需要,需要用到socket,需求是这样的,有很多台收集数据的服务器,另有三台用于监视的服务器,收集服务器向监视服务器发消息,然后监视服务器收到消息,改变相应灯的颜色。然后其中有两个窗体需要互相切换,后面决定用两个不同的端口去监听,这样就不会有数据丢失,因为发送可能同时往两个端口发消息。在这过程序中遇到很多问题,但现在很多问题都已解决了,由于任务时间紧,没有及时把遇到的问题发出来,也没有把解决方案记录下来,现在有很多都不知道怎么解决了。

?

???? 本人对java比较了解,对c#是门外汉,只有查资料,遇到问题就去百度,谷歌,我常去谷歌,习惯问题。现在因为总共有四个画面,然后写了个基类BaseForm,socket通信的服务器端代码封装到一个类里,因为想到公用,所以将这个服务器端类让他成为BaseForm的成员变量,想到什么时候开启服务,什么时候关闭服务,因为以前写过VB的程序,对WINFORM开发还是有所了解,只是发展太快,有很多年都没整了,很多东西就只有查呀,因为客户那边收集服务器发过来的消息分别用了28个端口来发的,服务器收也是用的28个端口来收的,因为每分钟都要发一次,数据大概10秒左右收集完毕,然后就在15或更后向服务器端发消息,然后在监视的服务器上实时的显示相应的状态。期间遇到些问题在这里说一下,

?? 1.有时候出现在绑定端口时出错,后面加了try catch就没有问题了,具体错误号记不得了,有时在收数据的时候出错

?? 2.控件跨线程访问,因为服务器上为了好调试,加了一个收到消息的显示控件,还有就是需要根据收到的消息及IP地址来显示相应位置的信息,Control.CheckForIllegalCrossThreadCalls = false;加了这句话就没问题了,控件就可以跨线程序访问了

? 3.经常出现访问已被回收的对象,因为用到异步通信,搞不懂该怎么回收资源,最后乱整整好了,好像是把开启的线程关了,把监听端口关了。

? 4.收到的数据怎么让他显示在相应的form上,后面经对c#比较熟的同事指点了下,说用委托,事件,后面就查了下MSDN,最后还还是用的事件,另外说一下,以前曾理解委托是怎么用了,结果久了不了,又忘了,好像当时想到委托就像是JAVA里的代理。晕了,搞不清楚,反正很少用,用的时候再说吧。

?

先说到上面这点吧,文笔有点差,大家将就看哈,从小语文就一直不及格。呵呵

?

?

先看一下用于发数据的客户端代码

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

namespace ClientSocketConsoleApplication
{
    // State object for receiving data from remote device.  
    public class StateObject
    {
        // Client socket.  
        public Socket workSocket = null;
        // Size of receive buffer.  
        public const int BufferSize = 256;
        // Receive buffer.  
        public byte[] buffer = new byte[BufferSize];
        // Received data string.  
        public StringBuilder sb = new StringBuilder();
    }

    public class AsynchronousClient
    {
        // The port number for the remote device.  
        //private const int port = 11000;

        // ManualResetEvent instances signal completion.  
        private static ManualResetEvent connectDone =
            new ManualResetEvent(false);
        private static ManualResetEvent sendDone =
            new ManualResetEvent(false);
        private static ManualResetEvent receiveDone =
            new ManualResetEvent(false);

        // The response from the remote device.  
        private static String response = String.Empty;

        string ip  ;
        string port;
        public AsynchronousClient(String remoIP, String remoport)
        {
             ip = remoIP;
             port = remoport;
        }

        public  void StartClient()
        {
            // Connect to a remote device.  
            try
            {
                // Establish the remote endpoint for the socket.  
                // The name of the   
                // remote device is "host.contoso.com".  
                
                int serverPort = Convert.ToInt32(port);
                IPAddress ipAddress = IPAddress.Parse(ip);// ipHostInfo.AddressList[0];
                IPEndPoint remoteEP = new IPEndPoint(ipAddress,serverPort);
                IPHostEntry ipHostInfo = Dns.GetHostByAddress(remoteEP.Address);

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

                // Connect to the remote endpoint.  
                client.BeginConnect(remoteEP,
                    new AsyncCallback(ConnectCallback), client);
                connectDone.WaitOne();

                Console.WriteLine("enter message!");
                String message = System.Console.ReadLine();
                // Send test data to the remote device.  
                Send(client, message+"<EOF>");
                sendDone.WaitOne();

                // Receive the response from the remote device.  
                Receive(client);
                receiveDone.WaitOne();

                // Write the response to the console.  
                Console.WriteLine("Response received : {0}", response);

                // Release the socket.  
                client.Shutdown(SocketShutdown.Both);
                client.Close();

            }
            catch (Exception e)
            {
                Console.WriteLine(e.ToString());
            }
        }

        private static void ConnectCallback(IAsyncResult ar)
        {
            try
            {
                // Retrieve the socket from the state object.  
                Socket client = (Socket)ar.AsyncState;

                // Complete the connection.  
                client.EndConnect(ar);

                Console.WriteLine("Socket connected to {0}",
                    client.RemoteEndPoint.ToString());

                // Signal that the connection has been made.  
                connectDone.Set();
            }
            catch (Exception e)
            {
                Console.WriteLine(e.ToString());
            }
        }

        private static void Receive(Socket client)
        {
            try
            {
                // Create the state object.  
                StateObject state = new StateObject();
                state.workSocket = client;

                // Begin receiving the data from the remote device.  
                client.BeginReceive(state.buffer, 0, StateObject.BufferSize, 0,
                    new AsyncCallback(ReceiveCallback), state);
            }
            catch (Exception e)
            {
                Console.WriteLine(e.ToString());
            }
        }

        private static void ReceiveCallback(IAsyncResult ar)
        {
            try
            {
                // Retrieve the state object and the client socket   
                // from the asynchronous state object.  
                StateObject state = (StateObject)ar.AsyncState;
                Socket client = state.workSocket;

                // Read data from the remote device.  
                int bytesRead = client.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));

                    // Get the rest of the data.  
                    client.BeginReceive(state.buffer, 0, StateObject.BufferSize, 0,
                        new AsyncCallback(ReceiveCallback), state);
                }
                else
                {
                    // All the data has arrived; put it in response.  
                    if (state.sb.Length > 1)
                    {
                        response = state.sb.ToString();
                    }
                    // Signal that all bytes have been received.  
                    receiveDone.Set();
                }
            }
            catch (Exception e)
            {
                Console.WriteLine(e.ToString());
            }
        }

        private static void Send(Socket client, String data)
        {
            // Convert the string data to byte data using ASCII encoding.  
            byte[] byteData = Encoding.ASCII.GetBytes(data);

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

        private static void SendCallback(IAsyncResult ar)
        {
            try
            {
                // Retrieve the socket from the state object.  
                Socket client = (Socket)ar.AsyncState;

                // Complete sending the data to the remote device.  
                int bytesSent = client.EndSend(ar);
                Console.WriteLine("Sent {0} bytes to server.", bytesSent);

                // Signal that all bytes have been sent.  
                sendDone.Set();
            }
            catch (Exception e)
            {
                Console.WriteLine(e.ToString());
            }
        }

        //public static int Main(String[] args)
        //{
        //    StartClient();
        //    return 0;
        //}
    }  
}

?启动类

using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
using yokohama.socketClient;

namespace ClientSocketConsoleApplication
{
    class Program
    {
        static void Main(string[] args)
        {
            AsynchronousClient client;

            if (args != null || args.Length == 2)
            {
                client = new AsynchronousClient(args[0], args[1]);
                client.StartClient();
            }
            
        }
    }
}

?socket监听类

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

namespace yokohama.socket
{
   

    public class AsynchronousSocketListener
    {
        public event EventHandler<SocketEventArgs> ReceiveCustomEvent;

        // Thread signal.  
        //public static ManualResetEvent allDone = new ManualResetEvent(false);
        public  ManualResetEvent allDone = new ManualResetEvent(false);
        private  int nPort = 10000;
        
        Thread mythread;

        Socket listener;

        bool listenerRun=true;

        public AsynchronousSocketListener(String port)
        {
            nPort = int.Parse(port);
        }

        private  void StartListening()
        {
            // Data buffer for incoming data.  
            byte[] bytes = new Byte[1024];

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

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

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

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

                    // Start an asynchronous socket to listen for connections.  
                    Console.WriteLine("Waiting for a connection...");
                    listener.BeginAccept(
                        new AsyncCallback(AcceptCallback),
                        listener);

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

            }
            catch (Exception e)
            {
                Console.WriteLine(e.ToString());
            }

            Console.WriteLine("\nPress ENTER to continue...");
            Console.Read();

        }

        //public static void AcceptCallback(IAsyncResult ar)
        public  void AcceptCallback(IAsyncResult ar)
        {
            // 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);
        }

        //public static void ReadCallback(IAsyncResult ar)
        public  void ReadCallback(IAsyncResult ar)
        {
            String content = String.Empty;

            // 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)
                {
                   EndPoint tempRemoteEP = handler.RemoteEndPoint;
                    IPEndPoint tempRemoteIP = (IPEndPoint)tempRemoteEP;
                    string rempip = tempRemoteIP.Address.ToString();
                    string remoport = tempRemoteIP.Port.ToString();

                    OnReceiveCustomEvent(new SocketEventArgs(rempip, remoport, content));
                    //if (ReceiveCustomEvent!=null)
                    //    ReceiveCustomEvent(null,new CustomEventArgs(rempip, content));
                    Console.WriteLine("Read {0} bytes from socket. \n ip : {1}",
                        content.Length, rempip);
                    // All the data has been read from the   
                    // client. Display it on the console.  
                    Console.WriteLine("Read {0} bytes from socket. \n 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);
                }
            }
        }

        //private static void Send(Socket handler, String data)
        private  void Send(Socket handler, String data)
        {
            // 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);
        }

        //private static void SendCallback(IAsyncResult ar)
        private  void SendCallback(IAsyncResult ar)
        {
            try
            {
                // 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);
                Console.WriteLine("Sent {0} bytes to client.", bytesSent);

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

            }
            catch (Exception e)
            {
                Console.WriteLine(e.ToString());
            }
        }
        
        public void StartService()
        {
            mythread = new Thread(new ThreadStart(StartListening));   
            mythread.Start();
        }

        public void StopService()
        {
            try
            {
                listenerRun = false;
               
                listener.Close();

                mythread.Abort();
                mythread = null;
                System.Console.WriteLine("与客户端断开连接!");
            }
            catch (Exception ex)
            {
                System.Console.WriteLine(ex.Message);
            }


        }

        protected virtual void OnReceiveCustomEvent(SocketEventArgs e)
        {
            EventHandler<SocketEventArgs> handler = ReceiveCustomEvent;

            if (handler != null)
            {
                //handler(this, e);
                handler(null, e);
            }
        }


        //public static int Main(String[] args)
        //{
        //    StartListening();
        //    return 0;
        //}
    }  
}

?事件参数类

using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;

namespace yokohama.socket
{
    public class SocketEventArgs : EventArgs
    {
        private string message;


        public string Message
        {
            get { return message; }
            set { message = value; }
        }

        private string ip;

        public string Ip
        {
            get { return ip; }
            set { ip = value; }
        }

        private string port;

        public string Port
        {
            get { return port; }
            set { port = value; }
        }

        public SocketEventArgs(string socketIp, string socketPort, string socketMessage)
        {
            ip = socketIp;
            port = socketPort;
            message = socketMessage;
            
        }
        
    }
}

?状态类

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

namespace yokohama.socket
{
    // State object for receiving data from remote device. 
    class StateObject
    {
        // Client socket.  
        public Socket workSocket = null;
        // Size of receive buffer.  
        public const int BufferSize = 256;
        // Receive buffer.  
        public byte[] buffer = new byte[BufferSize];
        // Received data string.  
        public StringBuilder sb = new StringBuilder();
    }
}
?

为了超了2W字,再来调整,我还是先发一次吧,需要继续看的,请看下一篇

发表评论
用户名: 匿名