首次成功后,Windows Mobile 6.5客户端套接字发送失败

时间:2015-01-08 11:28:52

标签: windows sockets mobile

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

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

我的开发/测试环境如下: 在Windows 7桌面上运行的控制台服务器应用 支架设备通过USB和Windows Mobile设备中心连接。

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

然而,当我尝试发送另一条消息(新套接字)时,应用程序失败。新的插座似乎第二次没有连接?

我收到以下异常: 的NullReferenceException 在 System.Net.LazyAsyncresult.InvokeCallback()中的SocketClient.ReceiveCallback() 在 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();
    }

}

感谢任何帮助。

1 个答案:

答案 0 :(得分:0)

没关系,我找到了解决办法:)

这将教我复制粘贴示例代码而不完全理解它。

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

我需要添加:

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

之前行......

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

我希望这可以帮助别人,因为我失去了一点头发,想出这个......