我试图通过TCP/IP连接建立通信,但在将C#client连接到Python服务器时遇到问题。
它抛出一个SocketException
:
System.Net.Sockets.SocketException: No connection could be made because the target machine actively refused it
我很确定它发生在它试图连接到Python服务器的那一行:sender.Connect(remoteEP);
socket.AF_INET
之前,我发现我在C#中对IP地址的解析似乎使其成为IPv6地址,所以我现在使用的是IPv6地址,但这并没有解决问题李>IPAddress.Parse(ip)
而不是首先使用Dns.GetHostEntry(ip)
获取主机,但这似乎没有起到任何作用李>C#代码:
using UnityEngine;
using System;
using System.Net;
using System.Net.Sockets;
using System.Collections;
using System.Text;
public class PyCommunicator : MonoBehaviour {
private string ip = "::1"; // Localhost
private int port = 14654;
public string dataStringToSend
{
get { return dataStringToSend; }
set { dataStringToSend = value; }
}
private void Start()
{
StartCoroutine(RequestServerCoroutine());
}
IEnumerator RequestServerCoroutine()
{
while (true)
{
RequestServer();
yield return new WaitForSecondsRealtime(10);
}
}
public void RequestServer()
{
byte[] bytes = new byte[1024]; // 1 KiloByte
try
{
// Connect to a Remote server,
// and get host IP Address that is used to establish a connection.
// In this case, we get one IP address of localhost that is IPv6 : ::1
// If a host has multiple addresses, you will get a list of addresses
IPHostEntry host = Dns.GetHostEntry(ip);
IPAddress ipAddress = host.AddressList[0];
IPEndPoint remoteEP = new IPEndPoint(ipAddress, port);
// Create a TCP/IP socket.
Socket sender = new Socket(AddressFamily.InterNetworkV6,
SocketType.Stream, ProtocolType.Tcp);
// Connect the socket to the remote endpoint. Catch any errors.
try
{
// Connect to Remote EndPoint
sender.Connect(remoteEP);
Debug.Log("Successfully established a connection between Unity and Python.");
// Encode the data string into a byte array.
dataStringToSend = "Test from C#";
if (dataStringToSend != "")
{
byte[] msg = Encoding.ASCII.GetBytes(dataStringToSend);
// Send the data through the socket.
int bytesSent = sender.Send(msg);
// Reset.
dataStringToSend = "";
}
// Receive the response from the remote device.
int bytesRec = sender.Receive(bytes);
Debug.LogFormat("Echoed test = {0}",
Encoding.ASCII.GetString(bytes, 0, bytesRec));
// Release the socket.
sender.Shutdown(SocketShutdown.Both);
sender.Close();
}
catch (ArgumentNullException ane)
{
Debug.LogFormat("ArgumentNullException: {0}", ane.ToString());
}
catch (SocketException se)
{
Debug.LogFormat("SocketException: {0}", se.ToString());
}
catch (Exception e)
{
Debug.LogFormat("Unexpected exception: {0}", e.ToString());
}
}
catch (Exception e)
{
Debug.LogFormat("Exception from setup: {0}", e.ToString());
}
}
}
C#代码取自客户机部分的this链接,并进行了修改以供我自己使用
Python代码:
import socket
from time import sleep
class Communicator():
def __init__(self, ip, port):
self.ip = ip
self.port = port
self.data_to_send = None
self.socket = None
self.socket_conn = None
self.socket_addr = None
# Start listening right away.
self.start()
def start(self):
"""Start listening and accept connection."""
self.socket = socket.socket(socket.AF_INET6, socket.SOCK_STREAM)
self.socket.bind((self.ip, self.port))
# Begin listening for 1 connection.
self.socket.listen(1)
print("Socket is listening on ip (" + str(self.ip) + ") and port " + str(self.port))
self.socket_conn, self.socket_addr = self.socket.accept()
print("Connection between Unity and Python established. Unity-C# is at: " + str(self.socket_addr))
sleep(5) # TESTING PURPOSES
# Receive.
result = ""
chunk_counter = 0
while True:
# Allow the server to read up to 1024 bytes.
data = self.conn.recv(1024)
chunk_counter += 1
# To minimize lag, read guess in chunks.
if chunk_counter < 5:
result += data.decode()
# If reading the guess is done,
# break out of loop.
if not data:
break
# Send.
self.socket.send("Test from python".encode())
# Close
self.socket.close()
def send_data(self):
"""Send data"""
pass
def receive_data(self):
"""Receive data"""
pass
Communicator('::1', 14654)
看来我在StackOverflow论坛上搜索得不够。 我在this中给出的代码和答案中找到了一个解决方案
我不需要使用实际的
localhost
环回地址,而是需要通过C#的DNS函数获取HOSTNAME
地址:我还在Python中使用了
socket.gethostname()
,这样它们在连接时就有了相同的地址我还将整个过程更改为使用IPv4地址,并在链接问题的答案中发现
host.AddressList
中的第一个元素包含IPv6地址,而第二个也是最后一个元素包含IPv4地址,这是缺少的部分更新代码
C#代码:
Python代码:
相关问题 更多 >
编程相关推荐