- android - RelativeLayout 背景可绘制重叠内容
- android - 如何链接 cpufeatures lib 以获取 native android 库?
- java - OnItemClickListener 不起作用,但 OnLongItemClickListener 在自定义 ListView 中起作用
- java - Android 文件转字符串
我尝试使用 TcpClient 类连接到远程计算机,但始终失败:
An unhandled exception of type 'System.Net.Sockets.SocketException' occurred in System.dll
Additional information: A connection attempt failed because the connected party did not properly respond after a period of time, or established connection failed because connected host has failed to respond
当客户端和服务器在本地时测试代码可以工作,但是当我尝试连接到远程计算机时,它不再工作。
这是服务器代码:
using System;
using System.Collections.Concurrent;
using System.Collections.Generic;
using System.Linq;
using System.Net;
using System.Net.Sockets;
using System.Net.WebSockets;
using System.Text;
using System.Threading;
using System.Threading.Tasks;
using System.Windows.Forms;
namespace WebSocketServer
{
class Program
{
static void Main(string[] args)
{
Console.WriteLine("Starting a new WebSockets server.");
WebSocketServer server = new WebSocketServer();
Console.WriteLine("The WebSocket server has started.");
bool userRequestedShutdown = false;
while (!userRequestedShutdown)
{
Console.ReadLine();
DialogResult result = MessageBox.Show("Do you want to shut the server down?", "Warning", MessageBoxButtons.YesNo, MessageBoxIcon.Warning);
if (result == DialogResult.Yes)
{
userRequestedShutdown = true;
}
}
server.Stop();
}
class WebSocketServer
{
TcpListener server;
Thread connectionListener;
ConcurrentDictionary<TcpClient, Thread> clients = new ConcurrentDictionary<TcpClient, Thread>();
public WebSocketServer()
{
server = new TcpListener(IPAddress.Parse("127.0.0.1"), (int)Properties.Settings.Default["Port"]);
try
{
server.Start();
}
catch (Exception exception)
{
Console.WriteLine("Error while trying to start the server: {0}", exception.ToString());
}
connectionListener = new Thread(() =>
{
while (true)
{
Console.WriteLine("Waiting for a new client.");
try
{
TcpClient client = server.AcceptTcpClient();
Thread clientListener = new Thread(() =>
{
try
{
NetworkStream stream = client.GetStream();
byte[] buffer = new byte[1024];
Console.WriteLine("Wating for the client to write.");
while (client.Connected)
{
try
{
int bytesRead = stream.Read(buffer, 0, buffer.Length);
Console.WriteLine("Read {0} bytes from the client.", bytesRead);
string data = Encoding.UTF8.GetString(buffer).Substring(0, bytesRead);
Console.WriteLine("Read the following string from the client: {0}", data);
}
catch (Exception exception)
{
Console.WriteLine("Error while trying to read from a TCP client: {0}", exception.ToString());
break;
}
}
Console.WriteLine("Client disconnected. Removing client.");
}
catch (Exception exception)
{
Console.WriteLine("Error while trying to connect to a TCP client: {0}", exception.ToString());
}
client.Close();
clients.TryRemove(client, out clientListener);
});
clientListener.Start();
clients.TryAdd(client, clientListener);
}
catch (Exception exception)
{
Console.WriteLine("Error while trying to accept a TCP client: {0}", exception.ToString());
}
Console.WriteLine("A client has connected.");
}
});
connectionListener.Start();
}
public void Stop()
{
server.Stop();
connectionListener.Abort();
}
}
}
}
这是客户端代码:
using System;
using System.Collections.Generic;
using System.Linq;
using System.Net;
using System.Net.Sockets;
using System.Text;
using System.Threading;
using System.Threading.Tasks;
namespace WebSocketClient
{
class Program
{
static void Main(string[] args)
{
Console.WriteLine("Opening up a TcpClient.");
TcpClient client = new TcpClient();
client.Connect("<Remote Hostname>", <RemotePortNumber>);
Console.WriteLine("TcpClient has connected.");
NetworkStream stream = client.GetStream();
bool closed = false;
new Thread(() =>
{
while (!closed)
{
Console.WriteLine("Writing data to the stream.");
byte[] bytes = Encoding.UTF8.GetBytes("Hello, world.");
stream.Write(bytes, 0, bytes.Length);
Thread.Sleep(1000);
}
}).Start();
Console.ReadLine();
closed = true;
}
}
}
那么这里有什么问题呢?我在 Azure 虚拟机上托管服务器,我已打开尝试用作 <RemotePortNumber>
的 TCP 端口在我的远程服务器上的 Windows 防火墙中,通过设置入站和出站规则以允许该端口上的所有流量进出计算机,并且我在 Azure 门户上创建了一个 TCP 端点,将虚拟机主机名的外部端口映射到我的虚拟机的内部专用端口,两者都设置为映射相同的端口号 <RemotePortNumber>
为了一致性。为了连接,我使用 <Remote Hostname>
<MyServiceName>.cloudapp.net
的值。我还尝试使用 IPAddress.Parse(<Public IP of my Azure Server>)
连接流但没有运气......它只是不断超时,好像我没有正确格式化主机名或其他东西。我缺少什么?如果有人可以提供一些有关如何调试问题的线索,那也会非常有帮助。
更新:运行 WireShark 跟踪,我看到很多这样的消息(这很糟糕吗?我认为如果我们考虑到 Azure 必须路由数据包,TCP 重新传输可能没问题从公共(public)域的端口到虚拟机的私有(private)端口,但不确定 RST、ACK 是什么):
更新:运行 Microsoft Message Analyzer,我在本地链路层上看到以下消息:
注意:我的虚拟机的内部 IP 为 100.75.20.78,公共(public) IP 为 191.238.37.130。它的公共(public)域名为 ovidius.cloudapp.net。我正在尝试在 TCP 端口 6490 上托管该应用程序。为了不放弃我的个人 IP 地址,我将其涂黑。
我已将 Azure 门户中的 TCP 端口从域映射到 VM,如下所示:
最佳答案
在花了两天的时间(填空)后,我在探索替代方法方面发挥了一点创意,尝试看看是否可以排除路由问题。我几乎可以肯定地得出结论,当您将公共(public)端口映射到同一个专用端口时,Microsoft 的虚拟机路由会失败。
例如,我尝试在下面设置新的 Socket 端点,它起作用了,因为它没有像我之前对 WebSocketServer 所做的那样将相同的域端口映射到相同的虚拟机端口:
更新:另外,在托管时,我必须设置服务器,不是在 IP 127.0.0.1 上,而是在内部 IP 上,在我的例子中是 100.75.20.78。
再次更新:与上述解决方案相反,我尝试删除 6490 处的旧端点并重新创建它,当我现在连接到该地址时,它似乎正在工作。我不完全确定为什么,我只能说这里唯一的区别是我在这次创建端点之前启用了防火墙规则以允许该端点的端口...不确定这是否会产生影响。老实说,我不确定是什么导致了这些问题。
再次更新:再想一下...我认为这可以归结为以下两个问题:
关于c# - TcpClient 未连接到远程服务器,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/24225531/
要关闭 TcpClient,必须关闭流。通常的做法是: client.GetStream().Close(); client.Close(); 因此仅使用 client
我正在阅读 the documentation on TcpClient.Close()并注意到这一点: Calling this method will eventually result in t
用于同步消息交换的我的客户端类: public class AsClient { private TcpClient connection; public AsClient(int s
我正在制作一个向许多 TCP 监听器发送数据的程序。如果不再使用其中一个 TCP 发送 channel ,我们是否需要使用 TCPClient.close 将其关闭。如果我们让它打开会怎样? 谢谢!
.NET 允许两种非常相似的方式从网络“读取”(假设 TCP 连接): 1. TcpClient.GetStream().Read() 2. TcpClient.Client.Receive() 通过
我找到了一些关于如何用 C# 编写 TCP/IP 客户端-服务器应用程序的代码服务器 Main 以此开头: TcpListener serverSocket = new TcpListener(888
我正在尝试连接到本地网络内的路由器。到目前为止,我已经使用了 TcpClient。 检查我的代码: public static void RouterConnect() {
服务器 : public class TcpServer { private TcpListener tcpListener; private static ManualResetEv
我想使用 TcpClient 发送 HTTP 请求。考虑以下代码: byte[] buf = new byte[1024]; string header = "GET
我在半关闭 TcpClient 时遇到了严重问题。我想做的是: 在客户端: 发送消息 关闭用于发送的底层套接字 收到回复 关闭用于读取的底层套接字(或者,此时,直接关闭它) 在服务器上: 接收消息 关
我有一个客户端和服务器,都有接收和发送方法,并且都使用相同的数据包类、数据包头大小和反序列化等。 如果我只发送较小的文本消息包,一切正常,但是当我尝试发送图像时,缓冲区溢出并且出现内存不足异常。奇怪的
在我的 C# 应用程序中,我有一个线程,它基本上不断地从 TcpClient 读取数据,直到被告知停止。为此,我使用 WaitHandles,例如: private ManualResetEvent
我有一个客户端-服务器程序。 我正在发送这样的数据: private void Sender(string s,TcpClient sock) { try { byte[] b
这个问题在这里已经有了答案: C# network connection running from shared drive (1 个回答) 关闭 7 年前。 我几天前问过类似的问题。那时,我正在尝
我有一个 TCPClient,它创建一个流,当 DataAvailable 时我从中读取流。 每 20 秒 !DataAvailable 我会使用 ACK 消息对套接字执行 ping 操作,以防止流关
我正在使用 SwifSockets:https://github.com/swiftsocket/SwiftSocket :按照有关如何使用它的说明后,我在堆栈溢出上找到了此代码:Sending Me
我在继承的一些代码中有一个奇怪的行为 - 下面的简化示例演示了如果内置到普通控制台应用程序中的问题。 WhoIs 在第 5 次调用时达到其使用限额 - 并返回一条消息 + 关闭套接字。使用 ReadL
我正在用 C# 开发一个 Tcp 客户端,我正在使用 TcpClient 类。我无法连接到服务器。 调试应用程序我可以看到对 Connect 的调用是成功的,但是在我这样做之后,我用 netstat
我有一个我似乎无法弄清楚的问题,请帮忙。我创建了一个类来处理使用 TcpClient 的某些硬件的接口(interface)。我希望此类在 HW 被销毁之前向 HW 发送最后一个命令。 为了解决这个问
您好,感谢您的帮助。这次想问一下TcpClient。我有一个服务器程序,我正在编写一个客户端程序。此客户端使用 TcpClient。首先是创建一个新客户端 clientSocket=new TcpCl
我是一名优秀的程序员,十分优秀!