简体   繁体   English

C#远程处理异常:每个套接字地址(协议/网络地址/端口)通常仅允许使用一种

[英]C# Remoting Exception : Only one usage of each socket address (protocol/network address/port) is normally permitted

I am using C# remoting for accessing a Label on the server system and the text of that label is to be changed by the click of a button on the client system. 我正在使用C#远程处理来访问服务器系统上的标签,并且该标签的文本将通过在客户端系统上单击按钮来更改。 I have made a remotable object in a class library naming RemoteObject and added the reference of this class library to both client and server system but when debugging both the server system and client system I am getting the exception "Only one usage of each socket address (protocol/network address/port) is normally permitted" 我在命名RemoteObject的类库中创建了一个可移动的对象,并将该类库的引用添加到客户端和服务器系统,但是在调试服务器系统和客户端系统时,我得到了一个例外:“每个套接字地址只能使用一种(协议/网络地址/端口)通常是允许的”

Please help me in this to rectify this issue.. 请对此提供帮助,以解决此问题。

RemotableObject.dll RemotableObject.dll

using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
using System.Windows.Forms;

namespace RemoteObject
{
    public class Class1 : MarshalByRefObject
    {
        public Class1()
        {
        }

        public void setText()
        {
            ServerClass bs = new ServerClass();
            Label lbl = bs.Controls["label1"] as Label;
            lbl.Text = "New Text";
        }
    }
}

Server Side Code 服务器端代码

using System;
using System.Collections.Generic;
using System.ComponentModel;
using System.Data;
using System.Drawing;
using System.Linq;
using System.Text;
using System.Windows.Forms;
using RemoteObject;
using System.Runtime.Remoting;
using System.Runtime.Remoting.Channels;
using System.Runtime.Remoting.Channels.Tcp;

namespace Server
{
    public partial class ServerClass : Form
    {
        private Class1 myremoteobject;
        public ServerClass()
        {
            InitializeComponent();
            myremoteobject = new Class1();
            TcpChannel channel = new TcpChannel(30000);
            ChannelServices.RegisterChannel(channel, true);
            RemotingConfiguration.RegisterWellKnownServiceType(typeof(Class1), "CSBU", WellKnownObjectMode.SingleCall);
        }

    }
}

Client Side Code 客户端代码

using System;
using System.Collections.Generic;
using System.ComponentModel;
using System.Data;
using System.Drawing;
using System.Linq;
using System.Text;
using System.Windows.Forms;
using RemoteObject;
using System.Runtime.Remoting;
using System.Runtime.Remoting.Channels;
using System.Runtime.Remoting.Channels.Tcp;


namespace Client
{
    public partial class ClientClass : Form
    {
        private Class1 remoteobject = new Class1();
        public ClientClass()
        {
            InitializeComponent();
            TcpChannel chan = new TcpChannel();
            ChannelServices.RegisterChannel(chan,true);
            remoteobject = (Class1)Activator.GetObject(typeof(Class1), "tcp://localhost:30000/CSBU");
        }

        private void changeTextBtn_Click(object sender, EventArgs e)
        {
            remoteobject.setText();
        }
    }
}

Please someone help me with the solution for this exception asap. 请有人帮助我尽快解决此异常。

It looks like the problem is that your Class1.setText method creates a new ServerClass . 看来问题在于您的Class1.setText方法创建了一个新的ServerClass Now since the thing that creates an instance of Class1 , and makes it available via remoting, is ServerClass , presumably that means that by the time your setText method is invoked remotely, you've already got one instance of ServerClass , so that'll end up creating a second. 现在,由于创建Class1实例并通过远程处理使其可用的东西是ServerClass ,这大概意味着到您远程调用setText方法时,您已经有了ServerClass一个实例,因此结束创造第二个。

This means that all the code in the ServerClass constructor runs twice. 这意味着ServerClass构造函数中的所有代码都运行两次。 The second time it runs, it'll be attempting to register a new TcpChannel on port 30000 for the second time. 第二次运行时,它将尝试第二次在端口30000上注册新的TcpChannel Since the channel you created first time round is already running, you get the error you describe. 由于您第一次创建的频道已在运行,因此您将得到描述的错误。

Try putting a breakpoint on your ServerClass constructor, and I'd expect that you'll see it run twice. 尝试在ServerClass构造函数上放置一个断点,我希望您会看到它运行两次。 The first time you won't get the error, but the second time you will. 第一次您不会收到错误,但是第二次您会得到。

The solution will be to avoid creating a new ServerClass in that setText method. 解决方案是避免在该setText方法中创建新的ServerClass If your intention is that the remoting call was supposed to modify a label in the form already on screen, then you need to pass a reference to the existing ServerClass instance to the Class1 instance. 如果您的意图是应该使用远程调用来修改屏幕上已经存在的表单中的标签,那么您需要将对现有ServerClass实例的引用传递给Class1实例。 (Eg, make the Class1 constructor take a ServerClass as an argument, and store that in a field. Use that instead of constructing a new one in setText .) (例如,使Class1构造函数将ServerClass作为参数,并将其存储在字段中。使用它而不是在setText中构造一个新的。)

By the way, remoting is more or less deprecated. 顺便说一句,远程处理或多或少已被弃用。 WCF is the usual way to do remote access in .NET these days. 目前,WCF是在.NET中进行远程访问的常用方法。 Either that or Web API. 要么是Web API。

Update:013/02/12 更新:013/02/12

Sorry, it has been a while since I used Remoting because, as I mentioned, Remoting is deprecated and you shouldn't be using it! 抱歉,自从我使用Remoting以来已经有一段时间了,因为正如我所提到的, Remoting已过时,您不应该使用它!

So, the thing I forgot: Remoting doesn't make it straightforward to register a particular well known instance - you register well-known types and Remoting wants to construct the type for you. 因此,我忘记了:远程处理并不能使注册一个特定的实例变得很简单-您注册了众所周知的类型,而远程处理则想为您构造类型。 So you'll need to come up with some other way of passing the ServerClass to your Class1 . 因此,您需要提出将ServerClass传递给Class1其他方法。

Eg: 例如:

public class Class1 : MarshalByRefObject
{
    public static ServerClass MyServer { get; set; }

    public void setText()
    {
        ServerClass bs = MyServer;
        Label lbl = bs.Controls["label1"] as Label;
        lbl.Text = "New Text";
    }
}

and then your ServerClass becomes: 然后您的ServerClass变为:

public partial class ServerClass : Form
{
    public ServerClass()
    {
        InitializeComponent();

        Class1.MyServer = this;

        TcpChannel channel = new TcpChannel(30000);
        ChannelServices.RegisterChannel(channel, true);
        RemotingConfiguration.RegisterWellKnownServiceType(typeof(Class1), "CSBU", WellKnownObjectMode.SingleCall);
    }
}

Then you'll hit your next error, an InvalidOperationException with the error "Cross-thread operation not valid: Control 'label1' accessed from a thread other than the thread it was created on." 然后,您将遇到下一个错误,即InvalidOperationException ,错误为“跨线程操作无效:控制从不是在其上创建线程的线程访问的'label1'。

This is because Remoting calls come in on worker threads, but you must only update Windows Forms UI elements from their owning UI thread. 这是因为Remoting调用是在辅助线程上进行的,但是您必须仅从其自己的UI线程更新Windows Forms UI元素。

Again, please don't use this because, as I may have mentioned before REMOTING IS DEPRECATED AND YOU SHOULDN'T BE USING IT; 再说一次,请不要使用它,因为正如我之前提到的,不建议使用REMOTE,并且您不应该使用它。 USE WCF but for what it's worth, here's how to deal with that: 使用WCF,但是对于它的价值,这里是如何处理它:

public void setText()
{
    MyServer.BeginInvoke((Action) setTextOnUiThread);
}

private void setTextOnUiThread()
{
    ServerClass bs = MyServer;
    Label lbl = bs.Controls["label1"] as Label;
    lbl.Text = "New Text";
}

And that should work. 那应该起作用。

And one more time, DON'T DO THIS - REMOTING IS NO LONGER A CURRENT TECHNOLOGY. 再有一次, 不要这样做-远程删除不再是当前的技术。 LOOK AT WCF INSTEAD 在WCF INSTEAD上查看

暂无
暂无

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

相关问题 c#中通常只允许每个套接字地址(协议/网络地址/端口)使用一次 - Only one usage of each socket address (protocol/network address/port) is normally permitted in c# c# udp 套接字通信 - 通常每个套接字地址(协议/网络地址/端口)只允许使用一次 - c# udp socket communication - Only one usage of each socket address (protocol/network address/port) is normally permitted 在 Redis C# 中批量创建密钥 - SocketException:通常每个套接字地址(协议/网络地址/端口)只允许使用一次 - bulk creating keys in Redis C# - SocketException: Only one usage of each socket address (protocol/network address/port) is normally permitted TCP套接字错误:通常只允许每个套接字地址(协议/网络地址/端口)使用一种 - TCP Socket Error: Only one usage of each socket address (protocol/network address/port) is normally permitted UDP客户端 - 创建socketOnly时的异常通常允许使用每个套接字地址(协议/网络地址/端口) - UDP Client - Exception in creating socketOnly one usage of each socket address (protocol/network address/port) is normally permitted 通常,每个套接字地址(协议/网络地址/端口)只能使用一种 - Only one usage of each socket address (protocol/network address/port) is normally permitted 通常,每个套接字地址(协议/网络地址/端口)只能使用一种 - Only one usage of each socket address (protocol/network address/port) is normally permitted 通常,每个套接字地址(协议/网络地址/端口)只能使用一种 - Only one usage of each socket address (protocol/network address/port) is normally permitted TcpListener:通常只允许每个套接字地址(协议/网络地址/端口)使用一种 - TcpListener : Only one usage of each socket address (protocol/network address/port) is normally permitted TCP Server:“通常只允许每个套接字地址(协议/网络地址/端口)使用一种。” - TCP Server : “Only one usage of each socket address (protocol/network address/port) is normally permitted.”
 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM