實現C#和Python高效率混合程式設計
為什麼C#和Python要屢屢進行混合程式設計呢?之前我們提到了使用託管C++封裝Python的核心庫為一個託管dll,然後供C#呼叫的途徑,這種方式算是一種比較科學的方式。但是它仍然有兩個小的問題,一來,我們是封裝了Win平臺的Python,使用的是託管C++,這就側面說明了這個託管dll是服從於.NET Framework的,而.NET Framework和Windows繫結。二來,我們如果通過原始碼的形式來呼叫Python,那麼Python簡易方便的編碼特性就會完全丟失。總結下來就是兩個缺點
1.無法跨平臺
2.無法進行優雅的程式設計
3.進行型別轉換的時候比較麻煩
麼提到混合程式設計,還是有非常多的方式的,這裡的話,我們實現一種最基本的方式,案例就採用C#和Python。
這種方式就是通過一種傳輸渠道,可以是檔案,也可以是任何的通訊渠道。(不管什麼渠道,它們都有一個特性,即它們的規範和實現它們的語言沒有任何關係)。此處我就可以通過socket來實現,如果是socket實現,那麼很好的解決了跨平臺和簡易程式設計的問題(此處的簡易程式設計指的是,如果我們通過封裝原始碼的形式來呼叫,則完全拋棄了語言的語法)
socket適用於很多不同的語言之間,現在我們嘗試用C#和Python來進行普通的交流
預設C#是服務端而Python是客戶端
class PyTransfer { //和Python語言進行socket通訊 //communicate with Python by socket Socket server; //伺服器套接字 Socket client; //使用者套接字 IPAddress ip; int port; //服務端ip和埠號 }
先宣告出我們需要的內容,隨後我們需要知道乙太網的ip地址,也就是本地伺服器的ip地址
public static string GetHostIP() { string ret = ""; IPAddress[] ips = Dns.GetHostEntry(Dns.GetHostName()).AddressList; foreach (IPAddress ip in ips) { if (ip.AddressFamily == AddressFamily.InterNetwork) { ret = ip.MapToIPv4().ToString(); } } if (ret == "") { return null; } return ret; }
寫了一個比較簡單的函式去實現,更多的內容可以參考計算機網路
然後是構造器當中的內容
class PyTransfer {
//和Python語言進行socket通訊
//communicate with Python by socket
Socket server; //伺服器套接字
Socket client; //使用者套接字
IPAddress ip;
int port; //服務端ip和埠號
public PyTransfer(string address,int port) {
server = new Socket(AddressFamily.InterNetwork, SocketType.Stream, ProtocolType.Tcp);
ip = IPAddress.Parse(address);
this.port = port;
server.Bind(new IPEndPoint(ip,port));
}
public static string GetHostIP()
{
string ret = "";
IPAddress[] ips = Dns.GetHostEntry(Dns.GetHostName()).AddressList;
foreach (IPAddress ip in ips)
{
if (ip.AddressFamily == AddressFamily.InterNetwork)
{
ret = ip.MapToIPv4().ToString();
}
}
if (ret == "")
{
return null;
}
return ret;
}
}
最後,我們開始伺服器的監聽。
public void StartRun() {
this.server.Listen(1); //開始監聽
while (true) {
Console.WriteLine("wait for client to connect...");
client = this.server.Accept();
break;
}
while (true) {
Console.Write("enter your message>>>");
string message = Console.ReadLine();
client.Send(System.Text.Encoding.Default.GetBytes(message.ToString()));
}
}
這樣,一套完整的伺服器就構建好了,雖然內容不是非常的完善,但是足夠提供我們能力去和Python交流了。
現在我們在主函式中把它例項化。
最後,我們再實現Python客戶端的程式碼即可。
import socket
ip = socket.gethostbyname(socket.gethostname())
port = 45535
server_address_family = (ip,port) #伺服器地址族
try:
client = socket.socket()
client.connect(server_address_family)
print("python has already connect to C#")
print("wait message from C#")
while 1:
msg = client.recv(1024)
print(msg.decode())
except Exception as e :
print(e)
print("連線失敗...")
完成之後,兩者執行的效果可以在下圖中看到。實現交流之後,我們就可以定義自己的協議,來規定什麼時候傳輸資料,什麼時候傳輸程式碼,什麼時候傳輸檔案等。如果不懂的問題,可以加我qq529324416,也可以加我的技術討論群493486382