Windows Mobile 6.5 客户端套接字发送在第一次成功后失败

Windows Mobile 6.5 client socket send fails after first success

我目前正在为运行 Windows Mobile 6.5 的扫描仪设备构建一个带有表单 UI 的客户端应用程序。 客户端应用程序需要通过 TCP 异步套接字与控制台服务器应用程序进行通信。

使用以下信息构建的服务器和客户端: Server & Client.

我的dev/test环境如下: 在 windows 7 桌面上运行的控制台服务器应用程序。 支架设备通过 USB 和 Windows 移动设备中心连接。

移动客户端应用设法连接到服务器,发送消息并最初收到响应。

然而,当我尝试发送另一条消息(新套接字)时,应用程序失败了。新的socket好像第二次连接不上?

我得到以下异常: 空引用异常 在 SocketClient.ReceiveCallback() 在 System.Net.LazyAsyncresult.InvokeCallback() 在 WorkerThread.doWork()...

代码如下:

using System;
using System.Net;
using System.Net.Sockets;
using System.Threading;
using System.Text;
using System.Collections.Generic;
using System.Windows.Forms;

namespace SeatScan
{
    static class Program
    {
        public static string serverIP;
        public static int serverPort;
        public static string response;
        public static string message = string.Empty;

        /// <summary>
        /// The main entry point for the application.
        /// </summary>
        [MTAThread]
        static void Main()
        {
            serverIP = MobileConfiguration.Settings["ServerIP"];
            serverPort = int.Parse(MobileConfiguration.Settings["ServerPort"]);

            Application.Run(new frmLogin());
        }

        public static void SendMessage(string message) 
        {
            SocketClient.StartClient(serverIP, serverPort, message);
            response = SocketClient.response;
        }
    }

    static class SocketClient
    {
        // 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.
        public static string response = String.Empty;

        public static void StartClient(string serverIP, int serverPort, string message)
        {
            response = String.Empty;
            // Connect to a remote device.
            try
            {
                // Establish the remote endpoint for the socket.
                IPAddress ipAddress = IPAddress.Parse(serverIP);
                IPEndPoint remoteEP = new IPEndPoint(ipAddress, serverPort);

                // Create a TCP/IP socket.
                Socket socket = new Socket(AddressFamily.InterNetwork, SocketType.Stream, ProtocolType.Tcp);
                //socket.SetSocketOption(SocketOptionLevel.Socket,SocketOptionName.DontLinger, false);
                //socket.SetSocketOption(SocketOptionLevel.Socket, SocketOptionName.ReuseAddress, true);

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

                MessageBox.Show("connect=" + socket.Connected, "Connecting?");

                // Send test data to the remote device.
                Send(socket, message);
                sendDone.WaitOne();

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

                // Release the socket.
                socket.Shutdown(SocketShutdown.Both);
                socket.Close();
                socket = null;
            }
            catch (Exception e)
            {
                //response = e.Message;
                //Console.WriteLine(e.ToString());
                MessageBox.Show(e.Message.ToString(), "StartClient");

            }
        }

        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());
                //MessageBox.Show("Socket connected to {0}", client.RemoteEndPoint.ToString());

                // Signal that the connection has been made.
                connectDone.Set();
            }
            catch (Exception e)
            {
                //Console.WriteLine(e.ToString());
                MessageBox.Show(e.Message.ToString(), "ConnectCallback");
            }
        }

        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());
                MessageBox.Show(e.Message.ToString(), "Receive");
            }
        }

        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());
                MessageBox.Show(e.Message.ToString() + e.InnerException.Message, "ReceiveCallback");
            }
        }

        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());
                MessageBox.Show(e.Message.ToString() + e.InnerException.Message, "SendCallback");
            }
        }
    }

    // State object for reading client data asynchronously
    public class StateObject
    {
        // Client  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();
    }

}

感谢任何帮助。

没关系,我找到了解决方案:)

这将教我在没有完全理解的情况下复制粘贴示例代码。

事实证明,由于我是在第一次连接后重新连接,所以我需要重置 ManualResetEvents 的状态...呃。

我需要补充:

connectDone.Reset();
sendDone.Reset();
receiveDone.Reset();

就在之前...

socket.BeginConnect(remoteEP, new AsyncCallback(ConnectCallback), socket);

我希望这对我失去了一点头发的人有所帮助...