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);
我希望这对我失去了一点头发的人有所帮助...
我目前正在为运行 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);
我希望这对我失去了一点头发的人有所帮助...