我目前正在为运行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();
}
}
感谢任何帮助。
答案 0 :(得分:0)
没关系,我找到了解决办法:)
这将教我复制粘贴示例代码而不完全理解它。
事实证明,由于我在第一次连接后重新连接,我需要重置ManualResetEvents的状态...... Duh。
我需要添加:
connectDone.Reset();
sendDone.Reset();
receiveDone.Reset();
之前行......
socket.BeginConnect(remoteEP, new AsyncCallback(ConnectCallback), socket);
我希望这可以帮助别人,因为我失去了一点头发,想出这个......