对于以下问题的任何帮助将不胜感激。我正在使用StreamSocketListener类在运行Windows IoT 10 Core的Raspberry Pi 3上接受TCP / IP连接。
到目前为止,这是我的服务器代码:
static string _maintenancePort = "8888";
public async static void StartListening()
{
try
{
StreamSocketListener listener = new StreamSocketListener();
var currentSetting = listener.Control.QualityOfService;
listener.Control.QualityOfService = SocketQualityOfService.LowLatency;
listener.ConnectionReceived += SocketListener_ConnectionReceived;
listener.Control.KeepAlive = true;
await listener.BindServiceNameAsync(_maintenancePort);
}
catch (Exception e)
{
Log.WriteErrorLog(e);
}
}
private static async void SocketListener_ConnectionReceived(StreamSocketListener sender, StreamSocketListenerConnectionReceivedEventArgs args)
{
try
{
Log.WriteDebugLog("Incoming data...");
Stream inStream = args.Socket.InputStream.AsStreamForRead();
StreamReader reader = new StreamReader(inStream);
string request = await reader.ReadLineAsync();
if (request != null)
{
Log.WriteDebugLog("Received : " + request);
}
}
catch (Exception e)
{
Log.WriteErrorLog(e);
}
}
我编写了以下客户端代码以连接到套接字。该代码在另一台计算机上运行。
// 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);
private static String response = String.Empty;
public static Socket client;
public static string SendMessageToClient(string ip, int port, string message, bool expectResponse)
{
// Connect to a remote device.
try
{
// Establish the remote endpoint for the socket.
IPAddress ipAddress = IPAddress.Parse(ip);
IPEndPoint remoteEP = new IPEndPoint(ipAddress, port);
// Create a TCP/IP socket.
client = new Socket(ipAddress.AddressFamily,SocketType.Stream, ProtocolType.Tcp);
// Connect to the remote endpoint.
client.BeginConnect(remoteEP, new AsyncCallback(ConnectCallback), client);
connectDone.WaitOne();
message += "^" + expectResponse.ToString();
// Send test data to the remote device.
Send(client, message);
sendDone.WaitOne();
// Receive the response from the remote device.
if (expectResponse)
{
Receive(client);
receiveDone.WaitOne();
}
// Release the socket.
client.Shutdown(SocketShutdown.Both);
client.Close();
return response;
}
catch (Exception e)
{
Log.Write(e, false);
return "";
}
}
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);
Log.WriteSingleMessage(String.Format("Sent {0} bytes to server.", bytesSent), false);
// Signal that all bytes have been sent.
sendDone.Set();
}
catch (Exception e)
{
Log.Write(e, false);
}
}
}
客户端代码由按钮单击事件触发。我面临的问题是上面的服务器代码只能运行一次。如果我将带有客户端代码的消息发送到服务器,则服务器将处理完美字符串。但是,如果我第二次按下该按钮,则会触发SocketListener_ConnectionReceived事件,但是没有数据传入。我为ConnectionReceived尝试了多个类,但是它们的行为都相同。
我在Raspberry Pi上用netstat检查了服务器是否正在监听。
TCP 0.0.0.0:8888 0.0.0.0:0侦听
甚至创建了子进程来处理连接,正如您期望从异步调用中进行的那样。客户端代码在收到已发送数据的消息(waitOne())并且客户端计算机上的套接字更改为CLOSE_WAIT后,关闭套接字。
TCP 10.0.102.10:8888 10.0.100.11:31298 CLOSE_WAIT
建立TCP 10.0.102.10:8888 10.0.100.11:31299
任何人都可以帮助我,并为我指出我做错了正确的方向。任何帮助将不胜感激。
答案 0 :(得分:0)
您可以尝试对套接字客户端使用同步方法而不是异步方法。它会工作。请参考以下代码:
public void SendMessageToClientSync(string ip, int port, string message, bool expectResponse)
{
// Data buffer for incoming data.
byte[] bytes = new byte[1024];
// Connect to a remote device.
try
{
// Establish the remote endpoint for the socket.
// This example uses port 11000 on the local computer.
IPAddress ipAddress = IPAddress.Parse(ip);
IPEndPoint remoteEP = new IPEndPoint(ipAddress, port);
// Create a TCP/IP socket.
Socket sender = new Socket(ipAddress.AddressFamily,
SocketType.Stream, ProtocolType.Tcp);
// Connect the socket to the remote endpoint. Catch any errors.
try
{
sender.Connect(remoteEP);
Console.WriteLine("Socket connected to {0}",
sender.RemoteEndPoint.ToString());
// Encode the data string into a byte array.
byte[] msg = Encoding.ASCII.GetBytes(message);
// Send the data through the socket.
int bytesSent = sender.Send(msg);
if(expectResponse)
{
// Receive the response from the remote device.
int bytesRec = sender.Receive(bytes);
Console.WriteLine("Echoed test = {0}",
Encoding.ASCII.GetString(bytes, 0, bytesRec));
}
// Release the socket.
sender.Shutdown(SocketShutdown.Both);
sender.Close();
}
catch (ArgumentNullException ane)
{
Console.WriteLine("ArgumentNullException : {0}", ane.ToString());
}
catch (SocketException se)
{
Console.WriteLine("SocketException : {0}", se.ToString());
}
catch (Exception e)
{
Console.WriteLine("Unexpected exception : {0}", e.ToString());
}
}
catch (Exception e)
{
Console.WriteLine(e.ToString());
}
}