C# TCP套接字-无效操作异常

C# TCP套接字-无效操作异常,c#,sockets,networking,C#,Sockets,Networking,我不熟悉C#的网络,在制作基本的客户机-服务器时遇到了一些问题。服务器运行正常,但当服务器启动且客户端尝试连接时,会抛出错误“套接字不得绑定或连接”。一些额外的详细信息是,服务器和客户端在同一台计算机上运行,并且禁用了ExclusivedAddressUse 客户端代码: this.client = new TcpClient(this.settings.GetByName("MasterServerIP").Value, int.Parse(this.settings.GetByName("M

我不熟悉C#的网络,在制作基本的客户机-服务器时遇到了一些问题。服务器运行正常,但当服务器启动且客户端尝试连接时,会抛出错误“套接字不得绑定或连接”。一些额外的详细信息是,服务器和客户端在同一台计算机上运行,并且禁用了ExclusivedAddressUse

客户端代码:

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.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.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方法调用,它仍然抛出相同的错误。有什么帮助吗?

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

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.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,因此之后的连接调用无效。移除它,它就会工作

从中,构造函数:

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


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

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.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,因此之后的连接调用无效。移除它,它就会工作

从中,构造函数:

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


当您使用主机和端口创建TCPClient时,它会自动连接。然后你就不需要再连接了

有关详细信息,请参阅

关于您的评论,当您删除connect调用时,它仍然失败,或者您仍在运行其他代码,或者出现了其他问题。以下代码运行良好:

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.exclusiveeaddressuse
的在线文档,您会注意到以下代码段(我的粗体):

在将基础套接字绑定到客户端端口之前,必须设置此属性。如果调用
Connect
BeginConnect
TcpClient(IPEndPoint)
,或
TcpClient(String,Int32),
客户端端口被绑定为该方法的一个副作用,随后无法设置ExclusivedAddressUse属性

事实上,以下代码:

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
,不要尝试将其与主机和端口构造函数一起使用,因为这将绑定套接字,尝试的属性更改将引发异常。相反,(作为一种可能性)使用无参数构造函数,更改属性,然后进行连接。

当您使用主机和端口创建TCPClient时,它会自动连接。然后你就不需要再连接了

有关详细信息,请参阅

关于您的评论,当您删除connect调用时,它仍然失败,或者您仍在运行其他代码,或者出现了其他问题。以下代码运行良好:

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.exclusiveeaddressuse
的在线文档,您会注意到以下代码段(我的粗体):

在将基础套接字绑定到客户端端口之前,必须设置此属性。如果调用
Connect
BeginConnect
TcpClient(IPEndPoint)
,或
TcpClient(String,Int32),
客户端端口被绑定为该方法的一个副作用,随后无法设置ExclusivedAddressUse属性

事实上,以下代码:

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
,不要尝试将其与主机和端口构造函数一起使用,因为这将绑定套接字,尝试的属性更改将引发异常。相反,(作为一种可能性)使用无参数构造函数,更改属性,然后连接。

我删除了连接,但它仍然抛出相同的错误。哈,这很奇怪。它是在服务器上还是在客户端上抛出错误?在哪一行上?它将它扔到我定义它的行上(this.client=new TcpClient等)。只是为了添加一些额外的信息,我没有为它设置一个值(private TcpClient client;)你认为这可能是因为服务器也绑定到同一台计算机、端口和ip吗?我删除了连接,但它仍然抛出相同的错误。哈,这很奇怪。它是在服务器上还是在客户端上抛出错误?在哪一行上?它将它扔到我定义它的行上(this.client=new TcpClient等)。只是为了添加一些额外的信息,我没有为它设置值(private TcpClient client;),您认为这可能是因为服务器也绑定到同一台计算机、端口和ip吗?删除connect方法调用后仍会抛出错误。@user1763295我建议这不是真的。我建议您没有运行正确的代码。@EJP,事实证明这是真的。这个错误是构造函数选择(绑定的构造函数)和试图更改绑定后无法更改的属性的组合。您是上帝派来的,解决了这个问题。你对这个问题的描述写得很好,所以我完全理解这个问题。再次感谢!这对我使用UDP客户端很有帮助:在使用绑定到端点的构造函数之后,必须在使用UD之前完成有关“ExclusiveAdressUse=false”的解决方案