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. 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”
Please help me in this to rectify this issue..
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.setTextmethod creates a newServerClass. Now since the thing that creates an instance ofClass1, and makes it available via remoting, isServerClass, presumably that means that by the time yoursetTextmethod is invoked remotely, you’ve already got one instance ofServerClass, so that’ll end up creating a second.This means that all the code in the
ServerClassconstructor runs twice. The second time it runs, it’ll be attempting to register a newTcpChannelon port 30000 for the second time. Since the channel you created first time round is already running, you get the error you describe.Try putting a breakpoint on your
ServerClassconstructor, and I’d expect that you’ll see it run twice. The first time you won’t get the error, but the second time you will.The solution will be to avoid creating a new
ServerClassin thatsetTextmethod. 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 existingServerClassinstance to theClass1instance. (E.g., make theClass1constructor take aServerClassas an argument, and store that in a field. Use that instead of constructing a new one insetText.)By the way, remoting is more or less deprecated. WCF is the usual way to do remote access in .NET these days. Either that or Web API.
Update: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!
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
ServerClassto yourClass1.E.g.:
and then your
ServerClassbecomes:Then you’ll hit your next error, an
InvalidOperationExceptionwith the error “Cross-thread operation not valid: Control ‘label1’ accessed from a thread other than the thread it was created on.”This is because Remoting calls come in on worker threads, but you must only update Windows Forms UI elements from their owning UI thread.
Again, please don’t use this because, as I may have mentioned before REMOTING IS DEPRECATED AND YOU SHOULDN’T BE USING IT; USE WCF but for what it’s worth, here’s how to deal with that:
And that should work.
And one more time, DON’T DO THIS – REMOTING IS NO LONGER A CURRENT TECHNOLOGY. LOOK AT WCF INSTEAD