使用C#通过局域网向Python发送/接收文件
我对Python开发相当陌生,需要一些帮助 我有一个控制器,我正计划把它用作家庭用品的控制器(比如在设定的时间打开泳池水泵)。我非常熟悉C#,想知道是否有一种方法可以编写一个C#用户界面,在笔记本电脑上运行,并通过局域网将数据以XML文件的形式发送到Raspberry Pi,告诉Pi该怎么做。我用C#编写了一些代码,用Python编写了一些代码来尝试发送和接收文件,但到目前为止,我的测试没有成功 我在Raspberry Pi上用Python编写了一些基本代码,用于控制一些GPIO引脚,我想知道这样的连接是否可行,我是否也应该将Python代码重写为C# 这是我的C#发送文件功能使用C#通过局域网向Python发送/接收文件,c#,python,sockets,raspberry-pi,lan,C#,Python,Sockets,Raspberry Pi,Lan,我对Python开发相当陌生,需要一些帮助 我有一个控制器,我正计划把它用作家庭用品的控制器(比如在设定的时间打开泳池水泵)。我非常熟悉C#,想知道是否有一种方法可以编写一个C#用户界面,在笔记本电脑上运行,并通过局域网将数据以XML文件的形式发送到Raspberry Pi,告诉Pi该怎么做。我用C#编写了一些代码,用Python编写了一些代码来尝试发送和接收文件,但到目前为止,我的测试没有成功 我在Raspberry Pi上用Python编写了一些基本代码,用于控制一些GPIO引脚,我想知道这
public void SendFile(string fileName)
{
try
{
string IpAddressString = piIP;
IPEndPoint ipEnd_client = new IPEndPoint(IPAddress.Parse(IpAddressString), portnumber);
Socket clientSock_client = new Socket(AddressFamily.InterNetwork, SocketType.Stream, ProtocolType.IP);
string filePath = "";
fileName = fileName.Replace("\\", "/");
Console.WriteLine(fileName);
while (fileName.IndexOf("/") > -1)
{
filePath += fileName.Substring(0, fileName.IndexOf("/") + 1);
fileName = fileName.Substring(fileName.IndexOf("/") + 1);
}
byte[] fileNameByte = Encoding.UTF8.GetBytes(fileName);
if (fileNameByte.Length > 5000 * 1024)
{
Console.WriteLine("File size is more than 5Mb, please try with small file.");
return;
}
Console.WriteLine("Buffering ...");
string fullPath = filePath + fileName;
byte[] fileData = File.ReadAllBytes(fullPath);
byte[] clientData = new byte[4 + fileNameByte.Length + fileData.Length];
byte[] fileNameLen = BitConverter.GetBytes(fileNameByte.Length);
fileNameLen.CopyTo(clientData, 0);
fileNameByte.CopyTo(clientData, 4);
fileData.CopyTo(clientData, 4 + fileNameByte.Length);
Console.WriteLine("Connection to server...");
clientSock_client.Connect(ipEnd_client);
Console.WriteLine("File sending...");
clientSock_client.Send(clientData, 0, clientData.Length, 0);
Console.WriteLine("Disconnecting...");
clientSock_client.Close();
Console.WriteLine("File [" + fullPath + "] transferred.");
}
catch (Exception ex)
{
if (ex.Message == "No connection could be made because the target machine actively refused it")
Console.WriteLine("File Sending fail. Because server not running.");
else
Console.WriteLine("File Sending fail. " + ex.Message);
return;
}
connected = true;
return;
}
import socket
import sys
s = socket.socket()
s.bind((socket.gethostname(), 8080))
s.listen(3)
while True:
#Accept connections from the outside
(clientsocket, address) = s.accept()
print(address)
i = 1
f = open('file_' + str(i) + ".xml", 'wb')
i = i + 1
while True:
l = clientsocket.recv(1024)
while l:
f.write(1)
l.clientsocket.recv(1024)
f.close()
sc.close()
s.close()
这是我的Python接收文件函数
public void SendFile(string fileName)
{
try
{
string IpAddressString = piIP;
IPEndPoint ipEnd_client = new IPEndPoint(IPAddress.Parse(IpAddressString), portnumber);
Socket clientSock_client = new Socket(AddressFamily.InterNetwork, SocketType.Stream, ProtocolType.IP);
string filePath = "";
fileName = fileName.Replace("\\", "/");
Console.WriteLine(fileName);
while (fileName.IndexOf("/") > -1)
{
filePath += fileName.Substring(0, fileName.IndexOf("/") + 1);
fileName = fileName.Substring(fileName.IndexOf("/") + 1);
}
byte[] fileNameByte = Encoding.UTF8.GetBytes(fileName);
if (fileNameByte.Length > 5000 * 1024)
{
Console.WriteLine("File size is more than 5Mb, please try with small file.");
return;
}
Console.WriteLine("Buffering ...");
string fullPath = filePath + fileName;
byte[] fileData = File.ReadAllBytes(fullPath);
byte[] clientData = new byte[4 + fileNameByte.Length + fileData.Length];
byte[] fileNameLen = BitConverter.GetBytes(fileNameByte.Length);
fileNameLen.CopyTo(clientData, 0);
fileNameByte.CopyTo(clientData, 4);
fileData.CopyTo(clientData, 4 + fileNameByte.Length);
Console.WriteLine("Connection to server...");
clientSock_client.Connect(ipEnd_client);
Console.WriteLine("File sending...");
clientSock_client.Send(clientData, 0, clientData.Length, 0);
Console.WriteLine("Disconnecting...");
clientSock_client.Close();
Console.WriteLine("File [" + fullPath + "] transferred.");
}
catch (Exception ex)
{
if (ex.Message == "No connection could be made because the target machine actively refused it")
Console.WriteLine("File Sending fail. Because server not running.");
else
Console.WriteLine("File Sending fail. " + ex.Message);
return;
}
connected = true;
return;
}
import socket
import sys
s = socket.socket()
s.bind((socket.gethostname(), 8080))
s.listen(3)
while True:
#Accept connections from the outside
(clientsocket, address) = s.accept()
print(address)
i = 1
f = open('file_' + str(i) + ".xml", 'wb')
i = i + 1
while True:
l = clientsocket.recv(1024)
while l:
f.write(1)
l.clientsocket.recv(1024)
f.close()
sc.close()
s.close()
同样,到目前为止,我甚至无法在两台设备之间建立连接。我应该从Pi开始,尝试C#而不是Python吗?还是我遗漏了什么?我已经给了这两台设备一个静态IP地址,并且现在在这两台机器上对IP地址进行了硬编码
编辑:
这是我从C#那里得到的控制台和堆栈跟踪:
缓冲。。。
连接到服务器。。。
System.dll中首次出现类型为“System.Net.Sockets.SocketException”的异常
文件发送失败。无法建立连接,因为目标计算机主动拒绝它10.51.21.199:8080
位于System.Net.Sockets.Socket.DoConnect(端点端点快照,SocketAddress SocketAddress)
位于System.Net.Sockets.Socket.Connect(端点remoteEP)
在中的App1.Stuffs.SendFile(字符串文件名)处
…Projects\App1\App1\Stuffs.cs:第308行
线程“”(0x1684)已退出,代码为0(0x0)。
尝试使用
s.bind(('', 8080))
强制Raspberry Pi侦听所有可用接口,因为socket.gethostname()
可能不是您实际期望的接口
更新:
在覆盆子皮的一面试试这个:
import socket
import sys
s = socket.socket()
s.bind(('', 8080))
s.listen(3)
i = 0
while True:
#Accept connections from the outside
(clientsocket, address) = s.accept()
print(address)
i = i + 1
with open('file_' + str(i) + ".xml", 'wb') as f:
while True:
l = clientsocket.recv(1024)
if not l:
break
f.write(l)
clientsocket.close()
s.close()
我有两种从Windows PC访问Raspberry Pi的方法。第一种是在PC上安装Putty connection manager后,输入RPi IP地址会在PC上生成一个终端窗口,在这里我可以执行RPi程序
在我的例子中,RPi连接到映射为驱动器T:的Windows工作组。我的C程序可以使用它在RPi上创建文件以供写入或读取。这是
f.write(l)
?stacktrace到底是什么?应该是@pnv,但现在我无法让C#程序发送任何东西。以下是控制台输出和stacktrace:缓冲到服务器的连接System.dll文件发送失败中发生了“System.Net.Sockets.SocketException”类型的第一次意外异常。无法建立连接,因为目标计算机在System.Net.Sockets.Socket.DoConnect(EndPoint endPointSnapshot,SocketAddress SocketAddress)的System.Net.Sockets.Socket.Connect(EndPoint remoteEP)的App1.Stuffs.SendFile(字符串文件名)处主动拒绝了它10.51.21.199:8080在……App1\Stuff.C:308中,既然您尝试集成C和Python,那么考虑使用IrPython可能是值得的:“IrPython是Python编程语言的一个开源实现,它与.NETFramework紧密集成。”@boardrider我不认为使用Iron会有任何区别,因为OP对Python或C#都不做任何特定的操作。“sc.close()”不应该是“clientsocket.close()”?不起作用。现在它说:文件发送失败。连接尝试失败,因为连接方在一段时间后没有正确响应,或者建立的连接失败,因为连接的主机没有响应10.51.21.199:8080,所以它没有拒绝连接。我会错过python端的某种握手吗?让它发送文件并连接!现在我认为Pi接收文件并以不同于C#发送文件的方式对其进行解码。每当我尝试打开.xml时,它都会说文档是空的,并且在文本编辑器中显示奇怪的字符。我应该在C#上以不同的方式对文件进行编码吗?@Thesila不太可能是编码问题,因为您不是在处理两侧的文本,而是二进制文件。出现此问题的原因可能是您在C#codebyte[]clientData=新字节[4+fileNameByte.Length+fileData.Length]中将文件名添加到文件内容中代码>您是否在Python端以某种方式处理它?如果没有,那么去掉它,您将在Pi上获得文件的逐位拷贝。