c# - c# Xamarin UWP/Android 服务器 - 客户端套接字 tcp 无法正确连接
问题描述
我项目的核心元素是使用套接字通过本地网络在两个应用程序(客户端和服务器)之间进行连接。我已经学习了很多教程,最稳定的版本是我将在下面发布的版本。
- 我已经在 c# 控制台应用程序上运行它并且工作正常
- 我已经在 Windows Forms 应用程序上运行它,它工作正常
所以我准备在我的 Xamarin 应用程序上实现它,并且有一次(第一次)它起作用了。我什至在我的 android 智能手机(作为客户端)和 Windows 上的 UWP(作为服务器)上对其进行了测试。在第一次之后,它再也没有工作过。在我的台式机和笔记本电脑上都没有。我实际上什么都没改变,它停止工作。
在我第一次接触套接字和 Xamarin 时,我认为它只是不起作用。但在那之后的工作时间。一定不是这样。
故障排除
我在 ClientSocket.Connect -> _socket.BeginConnect = false 上获取客户端类( ClientSocket )
- 我已经检查了防火墙,我已经卸载并禁用了防火墙
- 我已经检查了清单,即使在(必须拥有的权限)之后我尝试启用所有权限。
我会尝试上传一个保管箱链接(用于我的文件)
服务器代码:
namespace Control
{
[XamlCompilation(XamlCompilationOptions.Compile)]
public partial class HomePage : ContentPage
{
public HomePage()
{
InitializeComponent();
}
private void ServerConnectBtn_Clicked(object sender, EventArgs e)
{
ServerSocket.Bind(9000);
ServerSocket.Listen(500);
ServerSocket.Accept();
msg_lbl.Text = PacketHandler.status;
}
}
}
我的服务器类:
namespace Control.Server
{
class ServerSocket
{
private static Socket _socket;
private static byte[] _buffer = new byte[1024];
public ServerSocket()
{
_socket = new Socket(AddressFamily.InterNetwork, SocketType.Stream, ProtocolType.Tcp);
}
public static void Bind(int port)
{
_socket = new Socket(AddressFamily.InterNetwork, SocketType.Stream, ProtocolType.Tcp);
_socket.Bind(new IPEndPoint(IPAddress.Any, port));
}
public static void Listen(int backlog)
{
_socket.Listen(500);
}
public static void Accept()
{
_socket.BeginAccept(AcceptedCallback, null);
}
private static void AcceptedCallback(IAsyncResult result)
{
Socket clientSocket = _socket.EndAccept(result);
_buffer = new byte[1024];
clientSocket.BeginReceive(_buffer, 0, _buffer.Length, SocketFlags.None, ReceivedCallback, clientSocket);
Accept();
}
private static void ReceivedCallback(IAsyncResult result)
{
Socket clientSocket = result.AsyncState as Socket;
int bufferSize = clientSocket.EndReceive(result);
byte[] packet = new byte[bufferSize];
Array.Copy(_buffer, packet, packet.Length);
//Handle the packet
PacketHandler.Handle(packet, clientSocket);
_buffer = new byte[1024];
clientSocket.BeginReceive(_buffer, 0, _buffer.Length, SocketFlags.None, ReceivedCallback, clientSocket);
}
}
}
namespace Control.Server
{
public abstract class PacketStructure
{
private byte[] _buffer;
public PacketStructure(ushort length, ushort type)
{
_buffer = new byte[length];
WriteUshort(length, 0);
WriteUshort(type, 2);
}
public PacketStructure(byte[] packet)
{
_buffer = packet;
}
public void WriteUshort(ushort value, int offset)
{
byte[] tempbuffer = new byte[2];
tempbuffer = BitConverter.GetBytes(value);
Buffer.BlockCopy(tempbuffer, 0, _buffer, offset, 2);
}
public short ReadUshort(int offset)
{
return BitConverter.ToInt16(_buffer, offset);
}
public void WriteUint(uint value, int offset)
{
byte[] tempbuffer = new byte[4];
tempbuffer = BitConverter.GetBytes(value);
Buffer.BlockCopy(tempbuffer, 0, _buffer, offset,4);
}
public void WriteString(string value, int offset)
{
byte[] tempbuffer = new byte[value.Length];
tempbuffer = Encoding.UTF8.GetBytes(value);
Buffer.BlockCopy(tempbuffer, 0, _buffer, offset, value.Length);
}
public string ReadString(int offset, int count)
{
return Encoding.UTF8.GetString(_buffer, offset, count);
}
public byte[] Data { get { return _buffer; } }
}
}
namespace Control.Server
{
public static class PacketHandler
{
public static string status;
public static void Handle(byte[] packet, Socket clientSocket)
{
ushort packetLength = BitConverter.ToUInt16(packet, 0);
ushort packetType = BitConverter.ToUInt16(packet, 2);
status = "Received packet! Length: "+ packetLength + " | Type: "+ packetType;
switch (packetType)
{
case 2000:
Message msg = new Message(packet);
Console.WriteLine(msg.Text);
break;
}
}
}
}
namespace Control.Server
{
public class Message : PacketStructure
{
private string _message;
public Message(string message)
: base((ushort)(4 + message.Length), 2000)
{
Text = message;
}
public Message(byte[] packet)
: base(packet)
{
}
public string Text
{
get { return ReadString(4, Data.Length - 4); }
set
{
_message = value;
WriteString(value, 4);
}
}
}
}
客户端代码:
namespace Remote
{
[XamlCompilation(XamlCompilationOptions.Compile)]
public partial class SettingsPage : ContentPage
{
public SettingsPage()
{
InitializeComponent();
}
private void ClientConnectBtn_Clicked(object sender, EventArgs e)
{
ClientSocket.Connect("192.168.1.17",9000);
Status_lbl.Text = "Status : " +ClientSocket.status;
}
private void Send_Clicked(object sender, EventArgs e)
{
string msg = msgEntry.Text;
Message packet = new Message(msg);
ClientSocket.Send(packet.Data);
Status_lbl.Text = "Status : " + ClientSocket.status;
}
}
}
客户端类
namespace Remote.Client
{
public abstract class PacketStructure
{
private byte[] _buffer;
public PacketStructure(ushort length, ushort type)
{
_buffer = new byte[length];
WriteUshort(length, 0);
WriteUshort(type, 2);
}
public PacketStructure(byte[] packet)
{
_buffer = packet;
}
public void WriteUshort(ushort value, int offset)
{
byte[] tempbuffer = new byte[2];
tempbuffer = BitConverter.GetBytes(value);
Buffer.BlockCopy(tempbuffer, 0, _buffer, offset, 2);
}
public short ReadUshort(int offset)
{
return BitConverter.ToInt16(_buffer, offset);
}
public void WriteUint(uint value, int offset)
{
byte[] tempbuffer = new byte[4];
tempbuffer = BitConverter.GetBytes(value);
Buffer.BlockCopy(tempbuffer, 0, _buffer, offset, 4);
}
public void WriteString(string value, int offset)
{
byte[] tempbuffer = new byte[value.Length];
tempbuffer = Encoding.UTF8.GetBytes(value);
Buffer.BlockCopy(tempbuffer, 0, _buffer, offset, value.Length);
}
public string ReadString(int offset, int count)
{
return Encoding.UTF8.GetString(_buffer, offset, count);
}
public byte[] Data { get { return _buffer; } }
}
}
namespace Remote.Client
{
public class Message : PacketStructure
{
private string _message;
public Message(string message)
:base((ushort)(4 + message.Length), 2000)
{
Text = message;
}
public Message(byte[] packet)
:base(packet)
{
}
public string Text
{
get { return ReadString(4, Data.Length - 4); }
set
{
_message = value;
WriteString(value, 4);
}
}
}
}
namespace Remote.Client
{
class ClientSocket
{
private static Socket _socket;
private static byte[] _buffer;
public static string status;
public ClientSocket()
{
_socket = new Socket(AddressFamily.InterNetwork, SocketType.Stream, ProtocolType.Tcp);
}
public static void Connect(string ipAddress, int port)
{
_socket = new Socket(AddressFamily.InterNetwork, SocketType.Stream, ProtocolType.Tcp);
_socket.BeginConnect(new IPEndPoint(IPAddress.Parse(ipAddress), port), ConnectCallback, null);
}
private static void ConnectCallback(IAsyncResult result)
{
if (_socket.Connected)
{
status = "Connected to the server!";
_buffer = new byte[1024];
_socket.BeginReceive(_buffer, 0, _buffer.Length, SocketFlags.None, ReceiveCallback, null);
// throw new Exception("Conencted");
}
else
{
status = "Could not connect";
// throw new Exception("Could not connect");
}
}
private static void ReceiveCallback(IAsyncResult result)
{
int bufLength = _socket.EndReceive(result);
byte[] packet = new byte[bufLength];
Array.Copy(_buffer, packet, packet.Length);
//Handle packet
_buffer = new byte[1024];
_socket.BeginReceive(_buffer, 0, _buffer.Length, SocketFlags.None, ReceiveCallback, null);
}
public static void Send(byte[] data)
{
_socket.Send(data);
}
}
}
解决方案
推荐阅读
- java - 在 JOptionPane.ShowInputDialog 中验证用户输入
- bash - Find-While 进程替换和文件计数
- python - Django 管理员登录页面 - Python 崩溃
- angular - 带有 WebPack 的 Angular 7,发出 URL 长度为 11962 个字符的请求不起作用
- git - 视觉工作室中的 Git 提交
- c++ - 如何解决:在 Linux 上引导 CMake 时出错
- sap-cloud-sdk - 3.9.0 缺少 OData VDM 生成器 Maven JAR?
- excel - 将范围转换为数组
- python - Firestore 不导入 Blob,而是导入字符串值
- google-cloud-firestore - 被取代的 Cloud Datastore 上的“DatastoreException:缺少或不足的权限”