Have a large slow feed over a .NET asynchronous socket. Data is coming from instruments so can be 1 row a second (or more). Some times it can just stall.
Using there two examples from MSDN
asynchronous-client-socket-example
asynchronous-server-socket-example
I have a requirement from the socket client stop the transfer from the server mid stream. Each message is pretty small. Do not need to stop mid message. Need to be able to stop the loop - can receive 1000s of small messages (to client).
My thought is to save a reference to client and call:
client.Shutdown(SocketShutdown.Both);
client.Close();
Is this the correct approach?
private static Socket client;
private static void StartClient()
{
// Connect to a remote device.
try
{
// Establish the remote endpoint for the socket.
// The name of the
// remote device is "host.contoso.com".
//IPHostEntry ipHostInfo = Dns.GetHostEntry("host.contoso.com"); Dns.GetHostName()
IPHostEntry ipHostInfo = Dns.GetHostEntry(Dns.GetHostName());
IPAddress ipAddress = ipHostInfo.AddressList[0];
IPEndPoint remoteEP = new IPEndPoint(ipAddress, port);
// Create a TCP/IP socket.
Socket client = new Socket(ipAddress.AddressFamily,
SocketType.Stream, ProtocolType.Tcp);
//client = new Socket(ipAddress.AddressFamily,
// SocketType.Stream, ProtocolType.Tcp);
// Connect to the remote endpoint.
client.BeginConnect(remoteEP,
new AsyncCallback(ConnectCallback), client);
connectDone.WaitOne();
// Send test data to the remote device.
Send(client, "This is a test<EOF>");
sendDone.WaitOne();
// Receive the response from the remote device.
Receive(client);
receiveDone.WaitOne();
// Write the response to the console.
Console.WriteLine("Response received : {0}", response);
// Release the socket.
client.Shutdown(SocketShutdown.Both);
client.Close();
}
catch (Exception e)
{
Console.WriteLine(e.ToString());
}
}
Related
I'm make this TCP server in C# (UWP App in Win 10/11):
IPHostEntry ipHostInfo = Dns.GetHostEntry("localhost");
IPAddress ipAddress = ipHostInfo.AddressList[1]; //IP v4 address
IPEndPoint localEndPoint = new IPEndPoint(ipAddress, 21234);
System.Diagnostics.Debug.WriteLine("Wait on: " + localEndPoint.ToString());
Socket listener = new Socket(AddressFamily.InterNetwork,
SocketType.Stream, ProtocolType.Tcp);
// Bind the socket to the local endpoint and
// listen for incoming connections.
try
{
listener.Bind(localEndPoint);
listener.Listen(100);
// Start listening for connections.
while (true)
{
System.Diagnostics.Debug.WriteLine("Wait for a connection request...");
Socket handler = listener.Accept();
System.Diagnostics.Debug.WriteLine("Connection Request arrived!");
}//while
}//try
//...
and I have this client, written in C++ with boost::asio libraries:
using namespace boost::asio;
using ip::tcp;
boost::asio::io_context io_context;
tcp::resolver* resolver;
tcp::socket* socket_;
resolver = new tcp::resolver(io_context);
socket_ = new tcp::socket(io_context);
try
{
boost::asio::connect(*socket_, resolver->resolve("localhost", "21234"));
}
catch (std::exception& e)
{
std::cerr << "Connect Exception--->>" << e.what() << std::endl;
}
Ok, I obtain an exception from client:"Impossibile stabilire la connessione. Risposta non corretta della parte connessa dopo l'intervallo di tempo oppure mancata risposta dall'host collegato"("Unable to establish connection. Incorrect response from the connected party after the time interval or no response from the connected host").
I think that the wrong in the server because I tried successfully with a C++ boost::asio client and it work.
Where is wrong?
i want to let 2 c# apps each one is on a separate computer and both connected to the same ADSL router to send messages to each other i know that we have to use Sockets and tried many solutions on the internet but they are all working at the same computer but not working on a separate computers.
i believe that the problem is in the ip addresses but i tried a lot with no good results
is there any simple code to help please
i tried this function on server side
public static void StartServer()
{
IPHostEntry host = Dns.GetHostEntry("DESKTOP-SBJHC7I");
IPAddress ipAddress = host.AddressList[0];
Console.WriteLine(ipAddress.ToString());
IPEndPoint localEndPoint = new IPEndPoint(ipAddress, 11000);
try
{
// Create a Socket that will use Tcp protocol
Socket listener = new Socket(ipAddress.AddressFamily, SocketType.Stream, ProtocolType.Tcp);
// A Socket must be associated with an endpoint using the Bind method
listener.Bind(localEndPoint);
// Specify how many requests a Socket can listen before it gives Server busy response.
// We will listen 10 requests at a time
listener.Listen(10);
Console.WriteLine("Waiting for a connection...");
Socket handler = listener.Accept();
// Incoming data from the client.
string data = null;
byte[] bytes = null;
while (true)
{
bytes = new byte[1024];
int bytesRec = handler.Receive(bytes);
data += Encoding.ASCII.GetString(bytes, 0, bytesRec);
if (data.IndexOf("<EOF>") > -1)
{
break;
}
}
Console.WriteLine("Text received : {0}", data);
byte[] msg = Encoding.ASCII.GetBytes(data);
handler.Send(msg);
handler.Shutdown(SocketShutdown.Both);
handler.Close();
}
catch (Exception e)
{
Console.WriteLine(e.ToString());
}
Console.WriteLine("\n Press any key to continue...");
Console.ReadKey();
}
and this function in the client side
public static void StartClient()
{
byte[] bytes = new byte[1024];
try
{
// Connect to a Remote server
// Get Host IP Address that is used to establish a connection
// In this case, we get one IP address of localhost that is IP : 127.0.0.1
// If a host has multiple addresses, you will get a list of addresses
IPHostEntry host = Dns.GetHostEntry("DESKTOP-SBJHC7I");
IPAddress ipAddress = host.AddressList[0];
IPEndPoint remoteEP = new IPEndPoint(ipAddress, 11000);
// Create a TCP/IP socket.
Socket sender = new Socket(ipAddress.AddressFamily,
SocketType.Stream, ProtocolType.Tcp);
// Connect the socket to the remote endpoint. Catch any errors.
try
{
// Connect to Remote EndPoint
sender.Connect(remoteEP);
Console.WriteLine("Socket connected to {0}",
sender.RemoteEndPoint.ToString());
// Encode the data string into a byte array.
byte[] msg = Encoding.ASCII.GetBytes("This is a test<EOF>");
// Send the data through the socket.
int bytesSent = sender.Send(msg);
// Receive the response from the remote device.
int bytesRec = sender.Receive(bytes);
Console.WriteLine("Echoed test = {0}",
Encoding.ASCII.GetString(bytes, 0, bytesRec));
// Release the socket.
sender.Shutdown(SocketShutdown.Both);
sender.Close();
}
catch (ArgumentNullException ane)
{
Console.WriteLine("ArgumentNullException : {0}", ane.ToString());
}
catch (SocketException se)
{
Console.WriteLine("SocketException : {0}", se.ToString());
}
catch (Exception e)
{
Console.WriteLine("Unexpected exception : {0}", e.ToString());
}
}
catch (Exception e)
{
Console.WriteLine(e.ToString());
}
}
please make sure that your client is connected to the same IP on which server is started. because it seems in your code that your client connecting to host which you getting it from localhost identity. For your testing purpose please hardcode the Server's IP address in your Remoteendpoint. if still the issue same then I will share code to test on a different networks.
I have found this piece of code on the internet: it does not open a server listening on port 11000, as I hoped.
What can be the problem? I normally code in Delphi, so I am little lost. I have made a corresponding client in Delphi, which works.
I am using demo version of C# 2015.
public static void StartListening()
{
// Data buffer for incoming data.
byte[] bytes = new Byte[1024];
// Establish the local endpoint for the socket.
// Dns.GetHostName returns the name of the
// host running the application.
IPHostEntry ipHostInfo = Dns.Resolve(Dns.GetHostName());
IPAddress ipAddress = ipHostInfo.AddressList[0];
IPEndPoint localEndPoint = new IPEndPoint(ipAddress, 11000);
// Create a TCP/IP socket.
Socket listener = new Socket(AddressFamily.InterNetwork,
SocketType.Stream, ProtocolType.Tcp);
// Bind the socket to the local endpoint and
// listen for incoming connections.
try
{
listener.Bind(localEndPoint);
listener.Listen(10);
// Start listening for connections.
while (true)
{
//Console.WriteLine("Waiting for a connection...");
// Program is suspended while waiting for an incoming connection.
Socket handler = listener.Accept();
data = null;
// An incoming connection needs to be processed.
while (true)
{
bytes = new byte[1024];
int bytesRec = handler.Receive(bytes);
data += Encoding.ASCII.GetString(bytes, 0, bytesRec);
if (data.IndexOf("#") > -1)
{
break;
}
}
// Show the data on the console.
//Console.WriteLine("Text received : {0}", data);
// Echo the data back to the client.
byte[] msg = Encoding.ASCII.GetBytes(data);
handler.Send(msg);
handler.Shutdown(SocketShutdown.Both);
handler.Close();
}
}
catch (Exception e)
{
Console.WriteLine(e.ToString());
}
//Console.WriteLine("\nPress ENTER to continue...");
//Console.Read();
}
The problem might be here: Whats the IP address of ipHostInfo.AddressList[0] ? It might be the loop-back. I never restrict my server endpoint to an ip-adress unless I need to, but then I will specify it in a configfile.
IPEndPoint localEndPoint = new IPEndPoint(IPAddress.Any, 11000);
As per Jeroen's answer, encountered per .NET's Synchronous Server Socket Example. When listening/connecting to localhost, one should rather use
IPAddress ipAddress = IPAddress.Parse("127.0.0.1");
instead of
// Establish the local endpoint for the socket.
// Dns.GetHostName returns the name of the
// host running the application.
IPHostEntry ipHostInfo = Dns.GetHostEntry(Dns.GetHostName());
IPAddress ipAddress = ipHostInfo.AddressList[0];
Thanks for feedback. I found som other, older code:
TcpListener serverSocket = new TcpListener(11000);
that does the job. I know it is depreciated, but it works, actually.
I have an Android app (really Xamarin app) and I'm using Socket to listen on port 8888 on the Android app.
So, I want to connect to this port from another computer by tcp (from PC TO Android).
And, I receive the following error:
No connection could be made because the target machine actively refused it.
error 10061
My code (I got it from MS examples) works for two console apps. But if Android is server it doesn't work.
I try ping phone from pc, and it is OK.
My question: maybe should open a port? Or something else? How can I do this?
I will gladly to listen any ideas. Thanks.
My server code. C#, Xamarin.
using System;
using System.Net;
using System.Net.Sockets;
using System.Text;
using System.Threading;
using Android.Runtime;
using Java.Lang;
using Byte = System.Byte;
using Exception = System.Exception;
using String = System.String;
using StringBuilder = System.Text.StringBuilder;
// State object for reading client data asynchronously
public class StateObject
{
// Client socket.
public Socket workSocket = null;
// Size of receive buffer.
public const int BufferSize = 1024;
// Receive buffer.
public byte[] buffer = new byte[BufferSize];
// Received data string.
public StringBuilder sb = new StringBuilder();
}
public class AsynchronousSocketListener
{
// Thread signal.
public static ManualResetEvent allDone = new ManualResetEvent(false);
public AsynchronousSocketListener()
{
}
public static void StartListening()
{
// Data buffer for incoming data.
byte[] bytes = new Byte[1024];
IPAddress ipAddress = new IPAddress(new byte[] { 127, 0, 0, 1 });
IPEndPoint remoteEP = new IPEndPoint(ipAddress, 8888);
// Create a TCP/IP socket.
Socket listener = new Socket(AddressFamily.InterNetwork,
SocketType.Stream, ProtocolType.Tcp);
// Bind the socket to the local endpoint and listen for incoming connections.
try
{
listener.Bind(remoteEP);
listener.Listen(100);
while (true)
{
// Set the event to nonsignaled state.
allDone.Reset();
// Start an asynchronous socket to listen for connections.
Console.WriteLine("Waiting for a connection...");
listener.BeginAccept(
new AsyncCallback(AcceptCallback),
listener);
// Wait until a connection is made before continuing.
allDone.WaitOne();
}
}
catch (Exception e)
{
Console.WriteLine(e.ToString());
}
Console.WriteLine("\nPress ENTER to continue...");
Console.Read();
}
public static void AcceptCallback(IAsyncResult ar)
{
// Signal the main thread to continue.
allDone.Set();
// Get the socket that handles the client request.
Socket listener = (Socket)ar.AsyncState;
Socket handler = listener.EndAccept(ar);
// Create the state object.
StateObject state = new StateObject();
state.workSocket = handler;
handler.BeginReceive(state.buffer, 0, StateObject.BufferSize, 0,
new AsyncCallback(ReadCallback), state);
}
public static void ReadCallback(IAsyncResult ar)
{
String content = String.Empty;
// Retrieve the state object and the handler socket
// from the asynchronous state object.
StateObject state = (StateObject)ar.AsyncState;
Socket handler = state.workSocket;
// Read data from the client socket.
int bytesRead = handler.EndReceive(ar);
if (bytesRead > 0)
{
// There might be more data, so store the data received so far.
state.sb.Append(Encoding.ASCII.GetString(
state.buffer, 0, bytesRead));
// Check for end-of-file tag. If it is not there, read
// more data.
content = state.sb.ToString();
if (content.IndexOf("<EOF>") > -1)
{
// All the data has been read from the
// client. Display it on the console.
Console.WriteLine("Read {0} bytes from socket. \n Data : {1}",
content.Length, content);
// Echo the data back to the client.
Send(handler, content);
}
else
{
// Not all data received. Get more.
handler.BeginReceive(state.buffer, 0, StateObject.BufferSize, 0,
new AsyncCallback(ReadCallback), state);
}
}
}
private static void Send(Socket handler, String data)
{
// Convert the string data to byte data using ASCII encoding.
byte[] byteData = Encoding.ASCII.GetBytes(data);
// Begin sending the data to the remote device.
handler.BeginSend(byteData, 0, byteData.Length, 0,
new AsyncCallback(SendCallback), handler);
}
private static void SendCallback(IAsyncResult ar)
{
try
{
// Retrieve the socket from the state object.
Socket handler = (Socket)ar.AsyncState;
// Complete sending the data to the remote device.
int bytesSent = handler.EndSend(ar);
Console.WriteLine("Sent {0} bytes to client.", bytesSent);
handler.Shutdown(SocketShutdown.Both);
handler.Close();
}
catch (Exception e)
{
Console.WriteLine(e.ToString());
}
}
}
My client code. Just simple C# console app:
using System;
using System.Net;
using System.Net.Sockets;
using System.Text;
public class SynchronousSocketClient
{
public static void StartClient() {
// Data buffer for incoming data.
byte[] bytes = new byte[1024];
Console.WriteLine("Start!");
// Connect to a remote device.
try {
// Establish the remote endpoint for the socket.
// This example uses port 11000 on the local computer.
IPAddress ipAddress = new IPAddress(new byte[] { 10, 0, 1, 173 });
// IPAddress ipAddress = new IPAddress(new byte[] { 127, 0, 0, 1 });
IPEndPoint remoteEP = new IPEndPoint(ipAddress, 8888);
// Create a TCP/IP socket.
Socket sender = new Socket(AddressFamily.InterNetwork,
SocketType.Stream, ProtocolType.Tcp );
// Connect the socket to the remote endpoint. Catch any errors.
try {
sender.Connect(remoteEP);
Console.WriteLine("Socket connected to {0}",
sender.RemoteEndPoint.ToString());
// Encode the data string into a byte array.
byte[] msg = Encoding.ASCII.GetBytes("This is a test<EOF>");
// Send the data through the socket.
int bytesSent = sender.Send(msg);
// Receive the response from the remote device.
int bytesRec = sender.Receive(bytes);
Console.WriteLine("Echoed test = {0}",
Encoding.ASCII.GetString(bytes,0,bytesRec));
// Release the socket.
sender.Shutdown(SocketShutdown.Both);
sender.Close();
} catch (ArgumentNullException ane) {
Console.WriteLine("ArgumentNullException : {0}",ane.ToString());
} catch (SocketException se) {
Console.WriteLine("SocketException : {0}",se.ErrorCode);
Console.WriteLine("SocketException : {0}",se.SocketErrorCode);
Console.WriteLine("SocketException : {0}",se.ToString());
} catch (Exception e) {
Console.WriteLine("Unexpected exception : {0}", e.ToString());
}
} catch (Exception e) {
Console.WriteLine( e.ToString());
}
}
}
There are two separate scenarios for socket-based data transport (in a typical local lan setting where there is an ordinary isp router in place):
Any client app (including browser) that connects to a well-known server endpoint (specific ip address and port) and just connects to establish a tcp session, and never listens. This is no problem. The router allows allows outgoing connection attempts.
Any client app that wants to connect to another client app that is listening. This is more difficult in that the router in a local lan setting does not typically allow any incoming connection attempts to a local host. Further the router is probably doing NAT translation so it has an addressable internet-facing ip address and has configured a specific external port to route to a specific internal host machine that is presumably listening at a local address and port.
There are several ways to determine what this endpoint addressing mapping configuration is but none of them are very convenient. The key point is that the router will only open an internal host to communications from the external internet if that host has previously tried to tcp connect to that external host (whether it be a server or a peer client app). This works for the browser/website server configuration because the client is always doing the connecting so the router opens the communication channel for that specific addressed external server and allows incoming data to be received by the client (browser). It is a similar situation for udp data transport. The router will only open the internal host to external incoming udp data if the internal client has recently sent a message to that specific peer. Http (a Tcp variant) provides the client/server protocol that uses this router convention for browser/website connectivity and communications. But for the peer client that wants to act as both a client and a server, there are significant barriers. Of course local lan socket communications are no problem, as local ip addresses are available for any internal lan peer.
I am new to socket programming in C#. Have searched the web like crazy for the solution to my problem but didnt find anything that could fix it. So heres my problem:
I am trying to write a client-server application. For the time being, the server will also run on my local machine. The application transmits a byte stream of data from the client to the server. The problem is that the server doesnt detect a client request for connection, while the client is able to connect and transmit the byte stream.
here is the server code:
String strHostName = Dns.GetHostName();
Console.WriteLine(strHostName);
IPAddress ip = IPAddress.Parse("127.0.0.1");
ipEnd = new IPEndPoint(ip, port);
soc = new Socket(AddressFamily.InterNetwork, SocketType.Stream, ProtocolType.IP);
soc.Bind(ipEnd);
Console.WriteLine("Web Server Running... Press ^C to Stop...");
Thread th = new Thread(new ThreadStart(StartListen));
th.Start();
The StartListen thread is as below:
public void StartListen()
{
try
{
while (true)
{
string message;
Byte[] bSend = new Byte[1024];
soc.Listen(100);
if (soc.Connected)
{
Console.WriteLine("\nClient Connected!!\n==================\n CLient IP {0}\n", soc.RemoteEndPoint);
Byte[] bReceive = new Byte[1024 * 5000];
int i = soc.Receive(bReceive);
The client code is as follows:
hostIPAddress = IPAddress.Parse("127.0.0.1");
ipEnd = new IPEndPoint(hostIPAddress,port);
Socket clientSocket = new Socket(AddressFamily.InterNetwork, SocketType.Stream, ProtocolType.IP);
Console.WriteLine("Connecting to Server...");
clientSocket.Connect(ipEnd);
Console.WriteLine("Sending File...");
clientSocket.Send(clientData);
Console.WriteLine("Disconnecting...");
clientSocket.Close();
Console.WriteLine("File Transferred...");
Now what happens is that the server starts and when I run the client, it connects, sends and closes. But nothing happens on the server console, it doesnt detect any connection: if (soc.Connected) remains false.
I checked whether the server was listening to 127.0.0.1:5050 through netstat, and it sure was listening. Cant figure out the problem. Please help.
On the server side use Socket.Accept Method to accept incoming connection. The method returns a Socket for a newly created connection: the Send() and Receive() methods can be used for this socket.
For example, after accepting the separate thread can be created to process the client connection (i.e. client session).
private void ClientSession(Socket clientSocket)
{
// Handle client session:
// Send/Receive the data.
}
public void Listen()
{
Socket serverSocket = ...;
while (true)
{
Console.WriteLine("Waiting for a connection...");
var clientSocket = serverSocket.Accept();
Console.WriteLine("Client has been accepted!");
var thread = new Thread(() => ClientSession(clientSocket))
{
IsBackground = true
};
thread.Start();
}
}