I'm working to make a Client/Server Application in C# using winsock Control. I done every thing in that but i stuck the place of sending data from client to server. In my program server always listen the client using the ip and port. I send the data from the client to server.
1)When click the Listen button on the server form it open the server where client is connect.
2)In Client form 1st i click the connect button for that the server is connected Gives an message (Connect Event: ip) for this message we easly know that the client is connected to the server.
3)Then we enter some data in the Send Data text Box then click Send Button to send the data to server and also save in client.
Code Below:
SERVER:
using System;
using System.Collections.Generic;
using System.Windows.Forms;
using System.Net;
using System.Threading;
using System.Net.Sockets;
namespace Server
{
public partial class Form1 : Form
{
public Form1()
{
InitializeComponent();
}
const string DEFAULT_SERVER = "ip";
const int DEFAULT_PORT = 120;
System.Net.Sockets.Socket serverSocket;
System.Net.Sockets.SocketInformation serverSocketInfo;
public string Startup()
{
IPHostEntry hostInfo = Dns.GetHostByName(DEFAULT_SERVER);
IPAddress serverAddr = hostInfo.AddressList[0];
var serverEndPoint = new IPEndPoint(serverAddr, DEFAULT_PORT);
serverSocket = new System.Net.Sockets.Socket(System.Net.Sockets.AddressFamily.InterNetwork, System.Net.Sockets.SocketType.Stream, System.Net.Sockets.ProtocolType.Tcp);
serverSocket.Bind(serverEndPoint);
return serverSocket.LocalEndPoint.ToString();
}
public string Listen()
{
int backlog = 0;
try
{
serverSocket.Listen(backlog);
return "Server listening";
}
catch (Exception ex)
{
return "Failed to listen" + ex.ToString();
}
}
public string ReceiveData()
{
System.Net.Sockets.Socket receiveSocket;
byte[] buffer = new byte[256];
receiveSocket = serverSocket.Accept();
var bytesrecd = receiveSocket.Receive(buffer);
receiveSocket.Close();
System.Text.Encoding encoding = System.Text.Encoding.UTF8;
return encoding.GetString(buffer);
}
private void Listen_Click(object sender, EventArgs e)
{
string serverInfo = Startup();
textBox1.Text = "Server started at:" + serverInfo;
serverInfo = Listen();
textBox1.Text = serverInfo;
//string datatosend = Console.ReadLine();
//SendData(datatosend);
serverInfo = ReceiveData();
textBox1.Text = serverInfo;
//Console.ReadLine();
}
private void winsock_DataArrival(object sender, AxMSWinsockLib.DMSWinsockControlEvents_DataArrivalEvent e)
{
ReceiveData();
Listen();
}
private void winsock_ConnectEvent(object sender, EventArgs e)
{
Listen();
}
}
}
This all are work perfectly But here my problem is that i get data form the client to server at only one time. When i send data again from the client to the server its not working and gives me some Message like
Additional information: Only one usage of each socket address
(protocol/network address/port) is normally permitted
In the server form
serverSocket.Bind(serverEndPoint);
Please someone help me to solve my problem.
Thank you.
Try this. It helps you
delegate void AddTextCallback(string text);
public Form1()
{
InitializeComponent();
}
private void ButtonConnected_Click(object sender, EventArgs e)
{
ThreadPool.QueueUserWorkItem(new WaitCallback(ServerHandler));
}
private void ServerHandler(object state)
{
TcpListener _listner = new TcpListener(IPAddress.Parse("12.2.54.658"), 145);
_listner.Start();
AddText("Server started - Listening on port 145");
Socket _sock = _listner.AcceptSocket();
//AddText("User from IP " + _sock.RemoteEndPoint);
while (_sock.Connected)
{
byte[] _Buffer = new byte[1024];
int _DataReceived = _sock.Receive(_Buffer);
if (_DataReceived == 0)
{
break;
}
AddText("Message Received...");
string _Message = Encoding.ASCII.GetString(_Buffer);
AddText(_Message);
}
_sock.Close();
AddText("Client Disconnected.");
_listner.Stop();
AddText("Server Stop.");
}
private void AddText(string text)
{
if (this.listBox1.InvokeRequired)
{
AddTextCallback d = new AddTextCallback(AddText);
this.Invoke(d, new object[] { text });
}
else
{
this.listBox1.Items.Add(text);
}
}
I'm also have the same problem like you on last month but i solve that using this Receive multiple different messages TcpListener C# from stackoverflow. This helps me lot hope it helps to solve your problem also.
I'm not 100% sure you understand TCP sockets so here goes.
When you use a TCP listener socket you first bind to a port so that clients have a fixed, known point to connect to. This reserves the port for your socket until you give it up by calling Close() on that socket.
Next you Listen in order to begin the process of accepting clients on the port you bound to. You can do both this and the first step in one but as you haven't I haven't here.
Next you call Accept(). This blocks (halts execution) until a client connects and then it returns a socket which is dedicated to communication with that client. If you want to allow another client to connect, you have to call Accept() again.
You can then communicate with your client using the socket that was returned by Accept() until you're done, at which point you call Close() on that socket.
When you're done listening for new connections you call Close() on your listener socket.
However when you press your listen button the following happens:
You bind correctly, you begin listening correctly and then your call to ReceiveData() blocks on the Accept call until a client is received. You then receive some data (though this is TCP so that might not be the whole data!) and then you instantly close the connection to your client.
I presume to get the error you're getting you must then press listen again on your server. This therefore restarts the whole listener socket and when you get to bind to the port the second time your previous listener is still bound to it and thus the call fails because something's already allocated on that port.
Solution wise you need to keep the socket returned from the Accept() call open until you're done with it. Have the client handle the close by calling the Shutdown() method on their socket or establish some convention for marking the end of communication.
You're also going to run into trouble when you try and have multiple users connected and so at some point you're either going to require threads or some asynchronous sockets but I feel that's out the scope of this question.
I suggest you do not use AxMSWinsockLib.. Have a look at socket example given here where it shows how to create a client socket and server socket - https://msdn.microsoft.com/en-us/library/kb5kfec7(v=vs.110).aspx AND this one - https://msdn.microsoft.com/en-us/library/6y0e13d3(v=vs.110).aspx
Related
About the Code
I am using EasyModbus Nuget in C# Window Form Application. I am trying to fetch the changed Holding Register's Address Value through RTU(Real Time Update) using ModbusServer.
Below code connect to server.
void Connect() {
ModbusClient client = null;
client = new ModbusClient("IP Address", 502);
client.Connect();
}
Below code fetches the value of address given below Holding Register.
client.ReadHoldingRegisters(10001, 1);
So far, everything works perfectly.
I was reading about reading about Real Time Updates in EasyModbus. I found this link that can send the changed value of holding register automatically to the even handler.
Now, I have below code:
void Connect() {
ModbusServer ser = new ModbusServer();
ser.Port = Convert.ToInt32(Settings.Default.Port);
ser.Listen();
ser.HoldingRegistersChanged += Ser_HoldingRegistersChanged;
ModbusClient client = null;
client = new ModbusClient("IP Address", 502);
client.Connect();
}
private void Ser_HoldingRegistersChanged(int register, int numberOfRegisters)
{
}
When I run it, I get below error.
Only one usage of each socket address (protocol/network address/port)
is normally permitted
This error is occurring because I added the ModbusServer code.
Can you please suggest why this is happening?
Your problem isn't so serious and your main problem in this line
ser.Listen();
because your previous server socket is still in bound.
let's take a looks when a listen socket is in bound ?
obvious reason is when your listening socket send/receive packets but in rare conditions it happens when OS is NOT in ideal condition(100 % cpu usage and etc) then Releasing server socket might takes a minute to be released. in this condition when you run your server again the exception
Only one usage of each socket address (protocol/network address/port)
is normally permitted
happens.because , as i said before the previous server socket was not released yet.
Solution is
using different ports for different server sockets
or
use only one server socket which is initiated only once and check if it's connected or not.
// create the socket
public static Socket listenSocket = new Socket(AddressFamily.InterNetwork,
SocketType.Stream,
ProtocolType.Tcp);
// bind the listening socket to the port
IPAddress hostIP = (Dns.Resolve(IPAddress.Any.ToString())).AddressList[0];
IPEndPoint ep = new IPEndPoint(hostIP, port);
if(!listenSocket.IsBound){
listenSocket.Bind(ep);
// start listening
listenSocket.Listen(backlog);
}
// connect client
ModbusClient client = null;
client = new ModbusClient(hostIP , port);
client.Connect();
It seems you already have a server on the port and you try to add one more. Try the code below:
public partial class Form1 : Form
{
private int register = 0;
private readonly int port = 502;
private readonly List<ModbusServer> servers = new List<ModbusServer>();
private readonly List<ModbusClient> clients = new List<ModbusClient>();
public Form1()
{
InitializeComponent();
AppDomain.CurrentDomain.FirstChanceException +=
(sender, e) => MessageBox.Show(e.Exception.Message);
}
private void Foo(object sender, ThreadExceptionEventArgs e)
{
MessageBox.Show(e.Exception.Message);
}
private void Ser_HoldingRegistersChanged(int register, int numberOfRegisters) =>
MessageBox.Show($"register: {register}, numberOfRegisters: {numberOfRegisters}");
private void AddServer_Click(object sender, EventArgs e) =>
AddServerMethod();
private void AddClient_Click(object sender, EventArgs e) =>
AddClientMethod();
private void AddServerMethod()
{
var server = new ModbusServer { Port = port };
server.Listen();
server.HoldingRegistersChanged += Ser_HoldingRegistersChanged;
servers.Add(server);
MessageBox.Show("Server added.");
server.holdingRegisters[0] = 11; // register is changed, but no event is fired
}
private void AddClientMethod()
{
var client = new ModbusClient("127.0.0.1", port);
client.Connect();
clients.Add(client);
MessageBox.Show("Client added.");
client.WriteSingleRegister(register++, 11); // event is fired
}
}
If you click AddServer more than once you get the error you described. Btw, if you click AddClient before AddServer you get another error. Add one server and then add any number of clients. Each client writes a holding register and related event is fired with a message like this:
I'm trying to write a chat client/server in c# locally to get familiar with Sockets.
First I start the server with (very simplified) following code:
Server.cs
private readonly MessageManager _messageManager;
private readonly ChatServer _chatServer;
public ChatServerSkeleton()
{
_messageManager = new MessageManager();
_chatServer = new ChatServer();
Console.WriteLine("Server is running on: " + _messageManager.MyAddress);
}
Then I start the Client with +- same way, except I store the serveraddress in the client (I copied the server address into a prompt).
Client.cs
private readonly MessageManager _messageManager;
public ChatClient ChatClient { get; }
public ChatClientSkeleton(IPEndPoint serverAddress, string name)
{
_messageManager = new MessageManager();
ChatClient = new ChatClient(new ChatServerStub(serverAddress, _messageManager), name);
Console.WriteLine($"IPAddress of {name} is: {_messageManager.MyAddress}");
Console.WriteLine($"IPAddress of Server is: { serverAddress}");
}
MessageManager.cs
private readonly TcpListener _serverSocket;
public IPEndPoint MyAddress { get; }
public MessageManager()
{
try
{
//Create server socket on random port
_serverSocket = new TcpListener(IPAddress.Any, FindFreeTcpPort());
//Get host ip address
IPAddress[] localIps = Dns.GetHostAddresses(Dns.GetHostName());
IPAddress localhost = localIps.First(ip => ip.AddressFamily == AddressFamily.InterNetwork);
//Get port of serversocket
IPEndPoint ipEndPoint = _serverSocket.LocalEndpoint as IPEndPoint;
int port = ipEndPoint.Port;
//Create address
MyAddress = new IPEndPoint(localhost, port);
}
catch (Exception ex)
{
Console.Error.WriteLine("Something went wrong with the serversocket:");
Console.Error.WriteLine(ex);
}
}
FindFreeTcp port comes from here: https://stackoverflow.com/a/150974/5985593
Everything up till now seems to work. Let's say for example the server has now 192.168.0.219:51080 and the client 192.168.0.219:51085.
The problem occurs when I'm trying to send a message using this code in MessageManager.cs
public void Send(MethodCallMessage message, IPEndPoint address)
{
try
{
_serverSocket.Start();
TcpClient destination = new TcpClient(address.Address.ToString(), address.Port);
NetworkStream output = destination.GetStream();
MessageReaderWriter.Write(message, output);
destination.Close();
}
catch (Exception ex)
{
Console.Error.WriteLine("Failed to write a message:");
Console.Error.WriteLine(ex);
}
finally
{
_serverSocket.Stop();
}
}
More specific on the _server.Start(); line.
Anyone knows what I'm doing wrong?
Thanks in advance!
EDIT: it runs fine 1 time, when registering the client on the server. But after that if I want to send a message I get the SocketException where target machine actively refused.
I do use AcceptTcpClient() here:
MessageManager.cs
public MethodCallMessage WReceive()
{
MethodCallMessage result = null;
try
{
//_serverSocket.Start();
TcpClient client = _serverSocket.AcceptTcpClient();
NetworkStream input = new NetworkStream(client.Client, true);
result = MessageReaderWriter.Read(input);
client.Close();
}
catch (Exception ex)
{
Console.Error.WriteLine("Failed to receive a message:");
Console.Error.WriteLine(ex);
}
finally
{
//_serverSocket.Stop();
}
return result;
}
This method is used in the ServerSkeleton & ClientSkeleton as follows:
public void Run()
{
while (true)
{
MethodCallMessage request = _messageManager.WReceive();
HandleRequest(request);
}
}
So the flow is basically as follows:
I start the server (instantiate new messagemanager, 3rd snippet
and run serverskeleton (last snippet)
Server prints IP in
console, i copy the ip & start the client
Instantiate client &
set server ip to what I copy pasted
Start client skeleton (last
snippet)
A TcpListener that has called Start() listens for incoming connections and then stacks them on a queue. Once that queue is full then a socket exception results. To remove connections from the queue you need to use the AcceptTcpClient or AcceptSocket methods of TcpListener. This then gives you a connection that you can send and receive data on.
What I am guessing may be happening is that you receive your first incoming client, but dont accept and remove it to send and receive data on, and your subsequent connections are refused as the pending queue list is full (this is just a guess).
There is an overloaded method ... TcpListener.Start(int backlog) ... that allows you to set the size of the pending queue list (so you can have 5, 10 or more connections waiting to be accepted in the TcpListener)
With a server TCP socket the process is that you set it listening on a local address and a port. Clients then try to connect to that endpoint. When they connect the TCP listening socket accepts the connection and then passes that to a socket which is the socket on which data is transfered. The listening socket carries on listening for new connections, it doesnt itself transmit data.
I hope that makes sense ?
So the server would behave more like this ...
_serverSocket.Start();
TcpClient myAcceptedConnection = _serverSocket.AcceptTcpClient();
// in synchronous blocking socket situation the program flow halts
// here til a connection is established
// once you have a connection ... do stuff with myAcceptedConnection
if you wished to avoid the blocking scenario you can use TcpListener.Pending() to see if you have any connections waiting in the queue
EDIT 1:
Ok so the only weird thing I see is that you call the _serverSocket.Start() method in the MessageSend method ? A server doesnt normally start by sending out a message ... it normally waits listening for a connection, receives and reads the connection and then replies (or it might send out a greeting or such on connection).
Personally I would separate the listening aspect of the server from the sending and receiving of data ... have it in its own separate method, after all you want your server to be listening for incoming connections until you close it down. When you detect an incoming connection (perhaps by checking Pending() in a loop), then you can accept it and send and receive on the new TcpClient. When you are finished with whatever data you are transmitting/receiving on that client you can close it down , if thats what you want ... you dont need to close and open a tcp connection every time you send a message, you can leave it open til you are finished with it, in fact opening and closing tcp connections generates a bit of overhead in the handshake protocol that they go through.
There are caveats though ... Tcp connections can become "half open" especially with wireless which can lead to issues. Its a bit complicated to get into here, but I recommend this stellar set of articles by Stephen Cleary as a good read through. Read the whole blog, as there is a ton of good info in there.
So, back to simple, I would have ...
A serverStart() method where you start your server listening.
A serverAccept() method where you check if you have any pending connections and accept them if they are there.
A clientConnect() method for your client where you connect to a server
Read() and Write() methods for the server and the client where you do the data transmission.
Normally the flow would be ...
Server Listens
Client Connects
Server Accepts
Client Sends
Server Receives
(then server sends/receives, client sends/receives)
everything closes and shuts down
Hello everyone I am very new to Visual Studio, C# programming, and Windows Form Applications.
My need is very simple - I want to create my own small program to listen to data being sent by a GPS device over UDP. I do not need to communicate, just listen and see the data on the screen!
Something that works exactly the same as this :
http://sockettest.sourceforge.net/ (see 'UDP' tab)
My GPS device has an IP of 192.168.1.1 and sends a sting of numbers every 1 second, continuously, transmitting on UDP 25.255.255.255:5017.
All the examples on the internet seems to focus on 2-way communicate, client and server chat windows etc. There is a lot of confusing terminology like synchronous and a-synchronous, client, server, UDP, TCP, binding.
I just want an even more simplified program than the above example, where I can type in the port number 5017, click Start Listening, and then straight away works!
All advice and code examples very gratefully received!!
Many thanks,
Jon
I now have it working, and can receive data in a textbox in the UI!
I use button_start_Click to open the port and start receiving. However, I cannot get button_stop_Click to work. How can you stop/close/disconnect/endReceive using button click?
public Form1()
{
InitializeComponent();
}
private void button_start_Click(object sender, EventArgs e)
{
Client = new UdpClient(Convert.ToInt32(textBox_port.Text));
Client.BeginReceive(DataReceived, null);
}
private void DataReceived(IAsyncResult ar)
{
IPEndPoint ip = new IPEndPoint(IPAddress.Any, Convert.ToInt32(textBox_port.Text));
byte[] data;
try
{
data = Client.EndReceive(ar, ref ip);
if (data.Length == 0)
return; // No more to receive
Client.BeginReceive(DataReceived, null);
}
catch (ObjectDisposedException)
{
return; // Connection closed
}
// Send the data to the UI thread
this.BeginInvoke((Action<IPEndPoint, string>)DataReceivedUI, ip, Encoding.UTF8.GetString(data));
}
private void DataReceivedUI(IPEndPoint endPoint, string data)
{
txtLog.AppendText("[" + endPoint.ToString() + "] " + data + Environment.NewLine);
}
private void button_stop_Click(IAsyncResult ar) // NOT WORKING!! AGH!
{
IPEndPoint ip = new IPEndPoint(IPAddress.Any, Convert.ToInt32(textBox_port.Text));
byte[] data;
data = Client.EndReceive(ar, ref ip);
Client.Close();
}
Run the same code in background worker and then you can cancel the background worker anytime using backgroundworker.cancelasync().
Hope this helps.
I am trying to write a graphical C# program that can communicate with my Node.js server.
I am using UdpClient class and I am able to send some messages to the server.
However, I don't know how to receive UDP packages from the server.
JavaScript and Windows Form Widgets are event-driven, but UdpClient class in C# doesn't have any convenient events related to data reception.
Also, I don't know where to put the code of package reception. Most of online examples are console program and my program is GUI based.
I want my program to continuously listen at a port and when a package comes in, the program can capture the package and display its content in a TextBox.
Any suggestions ?
You can listen to a port asynchronously using BeginReceive. It works in GUI applications too - just remember to send the data to the UI thread before interacting with the UI.
This example is from a WinForms application. I've put a multiline textbox on the form called txtLog.
private const int MyPort = 1337;
private UdpClient Client;
public Form1() {
InitializeComponent();
// Create the UdpClient and start listening.
Client = new UdpClient(MyPort);
Client.BeginReceive(DataReceived, null);
}
private void DataReceived(IAsyncResult ar) {
IPEndPoint ip = new IPEndPoint(IPAddress.Any, MyPort);
byte[] data;
try {
data = Client.EndReceive(ar, ref ip);
if (data.Length == 0)
return; // No more to receive
Client.BeginReceive(DataReceived, null);
} catch (ObjectDisposedException) {
return; // Connection closed
}
// Send the data to the UI thread
this.BeginInvoke((Action<IPEndPoint, string>)DataReceivedUI, ip, Encoding.UTF8.GetString(data));
}
private void DataReceivedUI(IPEndPoint endPoint, string data) {
txtLog.AppendText("[" + endPoint.ToString() + "] " + data + Environment.NewLine);
}
I'm using the code below, it seem sometime the socket is not released
How did I found that?
by using process explorer(from sysinternal),
proprieties on the application
then going into TCP/IP tab.
I can see the port being used by typing "netstat -a" into a console
My problem is, after a while (like 5 weeks) there is like 40 port used by the application while it should be zero.
Anyone know why it does that?
public void Connect()
{
try {
// Resolve server address
IPHostEntry hostadd = Dns.GetHostEntry(TimeServer);
IPEndPoint EPhost = new IPEndPoint(hostadd.AddressList[0], 123);
//Connect the time server
UdpClient TimeSocket = new UdpClient();
TimeSocket.Connect(EPhost);
TimeSocket.Send(SNTPData, SNTPData.Length);
SNTPData = TimeSocket.Receive(ref EPhost);
TimeSocket.Close();
if (!IsResponseValid())
{
throw new Exception("Invalid response from " + TimeServer);
}
} catch(SocketException e)
{
throw new Exception(e.Message);
}
}
You're blocking forever on:
SNTPData = TimeSocket.Receive(ref EPhost);
If the socket never receives a packet it will sit there waiting until the process dies.
You'll need to close the socket by calling TimeSocket.Close() on a different thread or by setting a timeout on the receive using SetSocketOption.