0

我是 C# 网络的新手,在制作基本客户端服务器时遇到了一些麻烦。服务器运行正常,但是当服务器启动并且客户端尝试连接时,它会抛出错误“套接字不能被绑定或连接”。一些额外的细节是服务器和客户端正在同一台计算机上运行,​​并禁用了 ExclusiveAddressUse。

客户端代码:

this.client = new TcpClient(this.settings.GetByName("MasterServerIP").Value, int.Parse(this.settings.GetByName("MasterServerPort").Value)) { ExclusiveAddressUse = false };
this.client.Connect(IPAddress.Parse(this.settings.GetByName("MasterServerIP").Value), int.Parse(this.settings.GetByName("MasterServerPort").Value));
this.writer = new BinaryWriter(this.client.GetStream());
this.reader = new BinaryReader(this.client.GetStream());

服务器代码:

this.Listener.Start();
TcpClient tcpClient;
while (this.Listener.Server.Connected)
{
tcpClient = this.Listener.AcceptTcpClient();
System.Threading.Thread t = new System.Threading.Thread(() => { this.ProcessClient(tcpClient); }); //Runs the thing on another thread so this can be accepting another client
t.Start();
}

编辑:即使删除了 connect 方法调用,它仍然抛出相同的错误。有什么帮助吗?

4

2 回答 2

2

当您使用主机和端口创建 TCPClient 时,它会自动连接。然后,您无需再次连接。

有关详细信息,请参阅http://msdn.microsoft.com/en-us/library/System.Net.Sockets.TcpClient(v=vs.110).aspx

关于您的评论,即当您删除连接调用时它仍然失败,要么您仍在运行其他代码,要么还有其他问题。以下代码运行良好:

using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
using System.Net.Sockets;
namespace testtcp {
    class Program {
        static void Main(string[] args) {
            TcpClient client = new TcpClient("www.google.com", 80);
            //client.Connect("www.microsoft.com", 80);
        }
    }
}

但是,在您取消注释Connect呼叫的那一刻,您会得到一个SocketException带有解释性文本的:

{"A connect request was made on an already connected socket"}

但是,这实际上是与您收到的错误消息不同的错误消息,导致我们相信上面的“还有其他错误”声明。

如果您查看TcpClient.ExclusiveAddressUse 此处的在线文档,您会注意到以下代码片段(我的粗体字):

必须在底层套接字绑定到客户端端口之前设置此属性。如果您调用ConnectBeginConnectTcpClient(IPEndPoint)TcpClient(String, Int32),客户端端口被绑定为该方法的副作用,并且您不能随后设置 ExclusiveAddressUse 属性。

事实上,下面的代码:

using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
using System.Net.Sockets;
namespace testtcp {
    class Program {
        static void Main(string[] args) {
            TcpClient client = new TcpClient("www.google.com", 80) {
                ExclusiveAddressUse = false
            };
        }
    }
}

给你你描述的确切例外。

所以,最重要的是,如果你使用ExclusiveAddressUse,不要尝试将它与主机和端口构造函数一起使用,因为这将绑定套接字并且尝试的属性更改将引发异常。相反,(作为一种可能性)使用无参数构造函数,更改属性,然后连接。

于 2013-07-26T22:56:57.623 回答
1

问题出在客户端代码的前两行:

this.client = new TcpClient(this.settings.GetByName("MasterServerIP").Value, int.Parse(this.settings.GetByName("MasterServerPort").Value)) { ExclusiveAddressUse = false };
this.client.Connect(IPAddress.Parse(this.settings.GetByName("MasterServerIP").Value), int.Parse(this.settings.GetByName("MasterServerPort").Value));

当你在第一行调用构造函数时,你已经连接了 TcpClient,所以后面的 Connect 调用是无效的。删除它,它会工作。

docs,构造函数:

初始化 TcpClient 类的新实例并连接到指定主机上的指定端口。

于 2013-07-26T22:54:47.707 回答