通过 Tcp 问题发送鼠标坐标
Send Mouse Coordinates Over Tcp Issues
我正在开发一个程序,其中我想从我的电脑上移动远程电脑的光标,但是在远程电脑上接收鼠标坐标时出现了一个小问题,远程机器上的 tcp 服务器接收到的数据由于延迟而没有立即推送这里的某些地方是我保存在客户端发送和服务器接收文件中的代码和输出坐标。
发送坐标的客户端代码。
private void Form1_MouseMove(object sender, MouseEventArgs e)
{
if (isconnected)
{
try
{
NetworkStream serverStream = clientSocket.GetStream();
this.Cursor = new Cursor(Cursor.Current.Handle);
int pX = Cursor.Position.X;
int pY = Cursor.Position.Y;
byte[] outStream = System.Text.Encoding.ASCII.GetBytes($"{pX}#{pY}");
System.IO.File.AppendAllText(@"F:\DOWNLOAD\client.txt", $"{pX}#{pY}" + Environment.NewLine);
serverStream.Write(outStream, 0, outStream.Length);
serverStream.Flush();
}
catch (Exception ex)
{
}
}
}
接收坐标的服务器代码
while ((i = stream.Read(bytes, 0, bytes.Length)) != 0)
{
try
{
// Translate data bytes to a ASCII string.
// Receive mouse coordinates here
data = System.Text.Encoding.ASCII.GetString(bytes, 0, i);
string Coordinates = data.ToString();
string X = Coordinates.Substring(0, Coordinates.IndexOf('#'));
string Y = Coordinates.Substring(Coordinates.IndexOf('#') + 1);
coordvalue.Invoke((MethodInvoker)(() => coordvalue.Text = ""));
coordvalue.Invoke((MethodInvoker)(() => coordvalue.Text = $"{X} and {Y}"));
coordvalue.Invoke((MethodInvoker)(() => coordvalue.Update()));
// Change coordinates
System.Windows.Forms.Cursor.Position = new Point(Convert.ToInt32(X), Convert.ToInt32(Y));
Cursor.Clip = new Rectangle(this.Location, this.Size);
System.IO.File.AppendAllText(@"F:\DOWNLOAD\server.txt", $"{X} and {Y}" + Environment.NewLine);
}
catch (Exception E)
{
// MessageBox.Show(E.ToString());
}
}
从客户端发送坐标
653#492
659#490
669#489
677#486
684#483
693#476
699#470
709#460
715#453
720#444
724#437
在服务器上接收坐标
653和492
659和490
669和489
677和486
684和483
693和476
699和470
709和460715#453720#444
724 和 437
这里的问题是 709 和 460715#453720#444,因为旧坐标没有被向前推进并附加了不适合鼠标位置的新坐标。请帮助。
虽然您在 x 和 y 之间有一个分隔符,但您不会在消息之间传递分隔符,而是依赖于计时,正如您发现的那样不可靠。在 y 值后添加分隔符或 "end of message" 标记,并在服务器上对其进行解析,以确保不会同时收到两条消息。
您的问题是您将 TCP 视为块协议。其实不是,TCP是一种流媒体协议。唯一的保证是您发送了一些字节,并且它们将以相同的顺序接收。您可以发送一个 100 字节的块并接收 50 个 2 字节的块,或 1100 字节,或 100 个 1 字节的消息。您需要能够读取流并知道您需要多少数据并阻止直到您全部读取。
我会使用 c# 二进制编写器/reader。这会在长度信息之前添加长度信息,接收将等到它拥有所有内容。
我认为对于这种情况,使用二进制格式更好。
像这样:
private void Form1_MouseMove(object sender, MouseEventArgs e)
{
if (isconnected)
{
try
{
NetworkStream serverStream = clientSocket.GetStream();
var BW = new BinaryWriter(serverStream);
this.Cursor = new Cursor(Cursor.Current.Handle);
int pX = Cursor.Position.X;
int pY = Cursor.Position.Y;
BW.Write(pX);
BW.Write(pY);
}
catch (Exception ex)
{
}
}
}
private void RecieveLoop()
{
if (clientSocket.Available > 0)
{
NetworkStream serverStream = clientSocket.GetStream();
var BR = new BinaryReader(serverStream);
try
{
int X = BR.ReadInt32();
int Y = BR.ReadInt32();
coordvalue.Invoke((MethodInvoker)(() => coordvalue.Text = ""));
coordvalue.Invoke((MethodInvoker)(() => coordvalue.Text = $"{X} and {Y}"));
coordvalue.Invoke((MethodInvoker)(() => coordvalue.Update()));
////change coordinates
System.Windows.Forms.Cursor.Position = new Point(Convert.ToInt32(X), Convert.ToInt32(Y));
Cursor.Clip = new Rectangle(this.Location, this.Size);
System.IO.File.AppendAllText(@"F:\DOWNLOAD\server.txt", $"{X} and {Y}" + Environment.NewLine);
}
catch (Exception E)
{
// MessageBox.Show(E.ToString());
}
}
}
我正在开发一个程序,其中我想从我的电脑上移动远程电脑的光标,但是在远程电脑上接收鼠标坐标时出现了一个小问题,远程机器上的 tcp 服务器接收到的数据由于延迟而没有立即推送这里的某些地方是我保存在客户端发送和服务器接收文件中的代码和输出坐标。
发送坐标的客户端代码。
private void Form1_MouseMove(object sender, MouseEventArgs e)
{
if (isconnected)
{
try
{
NetworkStream serverStream = clientSocket.GetStream();
this.Cursor = new Cursor(Cursor.Current.Handle);
int pX = Cursor.Position.X;
int pY = Cursor.Position.Y;
byte[] outStream = System.Text.Encoding.ASCII.GetBytes($"{pX}#{pY}");
System.IO.File.AppendAllText(@"F:\DOWNLOAD\client.txt", $"{pX}#{pY}" + Environment.NewLine);
serverStream.Write(outStream, 0, outStream.Length);
serverStream.Flush();
}
catch (Exception ex)
{
}
}
}
接收坐标的服务器代码
while ((i = stream.Read(bytes, 0, bytes.Length)) != 0)
{
try
{
// Translate data bytes to a ASCII string.
// Receive mouse coordinates here
data = System.Text.Encoding.ASCII.GetString(bytes, 0, i);
string Coordinates = data.ToString();
string X = Coordinates.Substring(0, Coordinates.IndexOf('#'));
string Y = Coordinates.Substring(Coordinates.IndexOf('#') + 1);
coordvalue.Invoke((MethodInvoker)(() => coordvalue.Text = ""));
coordvalue.Invoke((MethodInvoker)(() => coordvalue.Text = $"{X} and {Y}"));
coordvalue.Invoke((MethodInvoker)(() => coordvalue.Update()));
// Change coordinates
System.Windows.Forms.Cursor.Position = new Point(Convert.ToInt32(X), Convert.ToInt32(Y));
Cursor.Clip = new Rectangle(this.Location, this.Size);
System.IO.File.AppendAllText(@"F:\DOWNLOAD\server.txt", $"{X} and {Y}" + Environment.NewLine);
}
catch (Exception E)
{
// MessageBox.Show(E.ToString());
}
}
从客户端发送坐标
653#492 659#490 669#489 677#486 684#483 693#476 699#470 709#460 715#453 720#444 724#437
在服务器上接收坐标 653和492 659和490 669和489 677和486 684和483 693和476 699和470 709和460715#453720#444 724 和 437
这里的问题是 709 和 460715#453720#444,因为旧坐标没有被向前推进并附加了不适合鼠标位置的新坐标。请帮助。
虽然您在 x 和 y 之间有一个分隔符,但您不会在消息之间传递分隔符,而是依赖于计时,正如您发现的那样不可靠。在 y 值后添加分隔符或 "end of message" 标记,并在服务器上对其进行解析,以确保不会同时收到两条消息。
您的问题是您将 TCP 视为块协议。其实不是,TCP是一种流媒体协议。唯一的保证是您发送了一些字节,并且它们将以相同的顺序接收。您可以发送一个 100 字节的块并接收 50 个 2 字节的块,或 1100 字节,或 100 个 1 字节的消息。您需要能够读取流并知道您需要多少数据并阻止直到您全部读取。
我会使用 c# 二进制编写器/reader。这会在长度信息之前添加长度信息,接收将等到它拥有所有内容。
我认为对于这种情况,使用二进制格式更好。
像这样:
private void Form1_MouseMove(object sender, MouseEventArgs e)
{
if (isconnected)
{
try
{
NetworkStream serverStream = clientSocket.GetStream();
var BW = new BinaryWriter(serverStream);
this.Cursor = new Cursor(Cursor.Current.Handle);
int pX = Cursor.Position.X;
int pY = Cursor.Position.Y;
BW.Write(pX);
BW.Write(pY);
}
catch (Exception ex)
{
}
}
}
private void RecieveLoop()
{
if (clientSocket.Available > 0)
{
NetworkStream serverStream = clientSocket.GetStream();
var BR = new BinaryReader(serverStream);
try
{
int X = BR.ReadInt32();
int Y = BR.ReadInt32();
coordvalue.Invoke((MethodInvoker)(() => coordvalue.Text = ""));
coordvalue.Invoke((MethodInvoker)(() => coordvalue.Text = $"{X} and {Y}"));
coordvalue.Invoke((MethodInvoker)(() => coordvalue.Update()));
////change coordinates
System.Windows.Forms.Cursor.Position = new Point(Convert.ToInt32(X), Convert.ToInt32(Y));
Cursor.Clip = new Rectangle(this.Location, this.Size);
System.IO.File.AppendAllText(@"F:\DOWNLOAD\server.txt", $"{X} and {Y}" + Environment.NewLine);
}
catch (Exception E)
{
// MessageBox.Show(E.ToString());
}
}
}