Socket Exception only when connecting over IP but not localhost - c#

System.Net.Sockets.SocketException (0x80004005): A connection attempt failed because the connected party did not properly respond after a period of time, or established connection failed because connected host has failed to respond
I only get this error when trying to connect via my public IP, if I use localhost it works fine.
My code:
(Note: Public IP/Local IP and Port have been censored here, but I'm using my public IPV4 Address and a specific port which has been Port forwarded as well as allowed through my computers firewall both inbound and outbound)
(Client):
`
using System;
using System.Collections.Generic;
using System.ComponentModel;
using System.Data;
using System.Drawing;
using System.Linq;
using System.Text;
using System.Threading.Tasks;
using System.Windows.Forms;
using System.Net;
using System.Net.Sockets;
namespace RemoteBG
{
public partial class Form1 : Form
{
Socket client;
IPEndPoint remote;
public Form1()
{
InitializeComponent();
IPHostEntry host = Dns.GetHostEntry("PUBLICIP");
IPAddress ipAddress = host.AddressList[0];
IPEndPoint remoteEP = new IPEndPoint(ipAddress, PORT);
Socket sender = new Socket(ipAddress.AddressFamily, SocketType.Stream, ProtocolType.Tcp);
client = sender;
remote = remoteEP;
}
private void TextUpdate(String s)
{
textBox1.AppendText(s + System.Environment.NewLine);
}
private void button1_Click(object sender, EventArgs e)
{
byte[] bytes = new byte[1024];
try
{
// Connect to Remote EndPoint
client.Connect(remote);
Console.WriteLine("Socket connected to {0}",
client.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 = client.Send(msg);
// Receive the response from the remote device.
int bytesRec = client.Receive(bytes);
Console.WriteLine("Echoed test = {0}",
Encoding.ASCII.GetString(bytes, 0, bytesRec));
// Release the socket.
client.Shutdown(SocketShutdown.Both);
client.Close();
}
catch (ArgumentNullException ane)
{
Console.WriteLine("ArgumentNullException : {0}", ane.ToString());
}
catch (SocketException se)
{
TextUpdate("Error connecting to Zang's PC. Error: " + se.ToString());
}
catch (Exception ex)
{
Console.WriteLine("Unexpected exception : {0}", ex.ToString());
}
}
private void button2_Click(object sender, EventArgs e)
{
}
}
}
Server:
using System;
using System.Net;
using System.Net.Sockets;
using System.Text;
namespace RemoteBGServer
{
class Program
{
public static int Main(String[] args)
{
StartServer();
return 0;
}
public static void StartServer()
{
IPHostEntry host = Dns.GetHostEntry("LOCALIP");
IPAddress ipAddress = host.AddressList[0];
IPEndPoint localEndPoint = new IPEndPoint(ipAddress, PORT);
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();
}
}
}
`
Expected to see the test message "This is a test" instead got the exception.
This only occurs when using my public ip for IPHostEntry. Localhost works as expected.
Confirmed that the port is forwarded and firewall has exceptions for the port

Related

Sockets in Unity

I'm working on a project that requires me to connect to an outside server from my oculus app, I want to do this via pushing a button. I have pretty limited C# knowledge, and would like someone to check my code. I can click the button just fine but initiating the connection doesn't seem to work.
using System.Collections;
using System.Collections.Generic;
using UnityEngine;
using System;
using System.Net;
using System.Net.Sockets;
using System.Text;
using UnityEngine.UI;
namespace Client
{
}
public class ConnectionCSClient : MonoBehaviour
{
}
public class Click : MonoBehaviour
{
}
class Program
{
public Button ConnectButton;
void Start()
{
Button Button = ConnectButton.GetComponent<Button>();
ConnectButton.onClick.AddListener(TaskOnClick); //Adds a listner on the button
}
void TaskOnClick()
{
if (Input.GetMouseButtonUp(0))
{
Debug.Log("Pressed left click.");
}
if (ConnectButton.onClick = true) try static void ExecuteClient();
{
{
// Establish the remote endpoint
// for the socket. This example
// uses port 11111 on the local
// computer.
IPHostEntry ipHost = Dns.GetHostEntry(Dns.GetHostName());
IPAddress ipAddr = ipHost.AddressList[0];
IPEndPoint localEndPoint = new IPEndPoint(ipAddr, 11111);
// Creation TCP/IP Socket using
// Socket Class Constructor
Socket sender = new Socket(ipAddr.AddressFamily,
SocketType.Stream, ProtocolType.Tcp);
try
{
// Connect Socket to the remote
// endpoint using method Connect()
sender.Connect(localEndPoint);
// We print EndPoint information
// that we are connected
Console.WriteLine("Socket connected to -> {0} ",
sender.RemoteEndPoint.ToString());
// Creation of message that
// we will send to Server
byte[] messageSent = Encoding.ASCII.GetBytes("Test Client<EOF>");
int byteSent = sender.Send(messageSent);
// Data buffer
byte[] messageReceived = new byte[1024];
// We receive the message using
// the method Receive(). This
// method returns number of bytes
// received, that we'll use to
// convert them to string
int byteRecv = sender.Receive(messageReceived);
Console.WriteLine("Message from Server -> {0}",
Encoding.ASCII.GetString(messageReceived,
0, byteRecv));
// Close Socket using
// the method Close()
sender.Shutdown(SocketShutdown.Both);
sender.Close();
}
// Manage of Socket's Exceptions
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());
}
}
}
Why do you think you need to work at the level of TCP sockets for this? That would be like opening up and removing the entire dashboard of your car just because the radio isn't working. You don't need to do that. HTTP is built on top of TCP and so HTTP is what you would use for web requests.
Unity provides the WebRequest class specifically for communicating with web servers.

How to read data from scale through ethernet using a client program

I have to connect Avery ZM510 scale to to a pc via ethernet. basically it should listen to the scale for data when user press print button. the suppliers said the scale is already configured as a server and gave an IP and said no need of a port number.
I tried below client program but no luck. Avery manuals also not containing any information about the API.
using System;
using System.Net;
using System.Net.Sockets;
using System.Text;
public class SocketClient
{
public static int Main(String[] args)
{
StartClient();
return 0;
}
public static void StartClient()
{
byte[] bytes = new byte[1024];
try
{
IPHostEntry host = Dns.GetHostEntry("localhost");
IPAddress ipAddress = host.AddressList[0];
IPEndPoint remoteEP = new IPEndPoint(ipAddress, "");
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);
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());
}
}
}
Configure Scale IP and port and any simple client program will work.
public partial class Form1 : Form
{
System.Net.Sockets.TcpClient clientSocket = new System.Net.Sockets.TcpClient();
public Form1()
{
InitializeComponent();
}
private void Form1_Load(object sender, EventArgs e)
{
msg("Client Started");
clientSocket.Connect("192.168.1.1", 8888); // Scale Ip and port
label1.Text = "Client Socket Program - Server Connected ...";
}
private void button1_Click(object sender, EventArgs e)
{
NetworkStream serverStream = clientSocket.GetStream();
byte[] outStream = System.Text.Encoding.ASCII.GetBytes(textBox2.Text + "$");
serverStream.Write(outStream, 0, outStream.Length);
serverStream.Flush();
byte[] inStream = new byte[10025];
serverStream.Read(inStream, 0, (int)clientSocket.ReceiveBufferSize);
string returndata = System.Text.Encoding.ASCII.GetString(inStream);
msg(returndata);
textBox2.Text = "";
textBox1.Focus();
}
public void msg(string mesg)
{
textBox1.Text = textBox1.Text + Environment.NewLine + " >> " + mesg;
}
Usually, when the AWTX ZM510 is sold, it is configured with a static IP to send a print string to 192.168.1.51 port 1. (unless the technical person that set it up changed these values.)
Test this socket, by opening the port in a terminal client, such as PuttY. (telnet 192.168.1.51:1) Then press the PRINT button.
Thereafter you can write your socket application in C#
--
My line of work is to provide technical support for Avery equipment - The ZM510 is a very capable device.

C# How to do to send more message to Server with Client?

Im writing a Client Server Socket C# with TCP protocoll to create sort of "Client Ask, Server Answer" But when I Execute first command my client close. I should put while somewhere but I don't know where. here is the code:
CLIENT
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];
// Connect to a remote device.
try
{
// Establish the remote endpoint for the socket.
// This example uses port 11000 on the local computer.
IPHostEntry ipHostInfo = Dns.Resolve(Dns.GetHostName());
IPAddress ipAddress = ipHostInfo.AddressList[0];
IPEndPoint remoteEP = new IPEndPoint(ipAddress, 11000);
// 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());
Console.WriteLine("Insert text to send to server");
String a = Console.ReadLine(); //This is a test<EOF>
// Encode the data string into a byte array.
byte[] msg = Encoding.ASCII.GetBytes(a);
// 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());
}
}
public static int Main(String[] args)
{
StartClient();
//To avoid Prompt disappear
Console.Read();
return 0;
}
}
SERVER
using System;
using System.Net;
using System.Net.Sockets;
using System.Text;
using System.Collections;
using System.IO;
//using System.Diagnostics;
public class SynchronousSocketListener
{
// Incoming data from the client.
public static string data = null;
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);
byte[] msg = null;
// 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.Equals("ping"))
{
// Show the data on the console.
Console.WriteLine("Text received : {0}", data);
// Echo the data back to the client.
msg = Encoding.ASCII.GetBytes("pong");
handler.Send(msg);
break;
}
if (data.Equals("dir"))
{
// Show the data on the console.
Console.WriteLine("Text received : {0}", data);
// Echo the data back to the client.
msg = Encoding.ASCII.GetBytes(System.AppDomain.CurrentDomain.BaseDirectory);
handler.Send(msg);
break;
}
if (data.Equals("files"))
{
// Show the data on the console.
Console.WriteLine("Text received : {0}", data);
String files = "";
string[] fileEntries = Directory.GetFiles(System.AppDomain.CurrentDomain.BaseDirectory);
foreach (string fileName in fileEntries)
files += ProcessFile(fileName);
// Echo the data back to the client.
msg = Encoding.ASCII.GetBytes(files);
handler.Send(msg);
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();
}
public static String ProcessFile(string path)
{
return path += "\n\n" + path;
}
public static void ProcessDirectory(string targetDirectory)
{
// Process the list of files found in the directory.
string[] fileEntries = Directory.GetFiles(targetDirectory);
foreach (string fileName in fileEntries)
ProcessFile(fileName);
// Recurse into subdirectories of this directory.
string[] subdirectoryEntries = Directory.GetDirectories(targetDirectory);
foreach (string subdirectory in subdirectoryEntries)
ProcessDirectory(subdirectory);
}
public static int Main(String[] args)
{
StartListening();
return 0;
}
}
Now If you copy paste this code and execute Server and then Client, you can write something into CLient prompt and get an answers but at 2 attempt CLient close because there is no while that continues the process! I tried put while out of try and into but code crashed! An Help would be appreciate an help or solution is the same, just get an answer :)
Thank you everyone
I have limited knowledge working with sockets. However I know you should only call the following once:
Socket handler = listener.Accept();
I added a while loop under the above line and also removed your break statements at the end of your if conditions.
So the new code becomes:
CLIENT
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];
// Connect to a remote device.
try
{
// Establish the remote endpoint for the socket.
// This example uses port 11000 on the local computer.
IPHostEntry ipHostInfo = Dns.Resolve(Dns.GetHostName());
IPAddress ipAddress = ipHostInfo.AddressList[0];
IPEndPoint remoteEP = new IPEndPoint(ipAddress, 11000);
// 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());
while (true)
{
Console.WriteLine("Insert text to send to server");
String a = Console.ReadLine(); //This is a test<EOF>
// Encode the data string into a byte array.
byte[] msg = Encoding.ASCII.GetBytes(a);
// 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());
}
}
public static int Main(String[] args)
{
StartClient();
//To avoid Prompt disappear
Console.Read();
return 0;
}
}
SERVER
using System;
using System.Net;
using System.Net.Sockets;
using System.Text;
using System.Collections;
using System.IO;
//using System.Diagnostics;
public class SynchronousSocketListener
{
// Incoming data from the client.
public static string data = null;
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.
while (true)
{
try
{
//if (!listener.IsBound)
//{
listener.Bind(localEndPoint);
//}
listener.Listen(10);
byte[] msg = null;
// 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();
while (true)
{
data = null;
// An incoming connection needs to be processed.
bytes = new byte[1024];
int bytesRec = handler.Receive(bytes);
data += Encoding.ASCII.GetString(bytes, 0, bytesRec);
if (data.Equals("ping"))
{
// Show the data on the console.
Console.WriteLine("Text received : {0}", data);
// Echo the data back to the client.
msg = Encoding.ASCII.GetBytes("pong");
handler.Send(msg);
//break;
}
if (data.Equals("dir"))
{
// Show the data on the console.
Console.WriteLine("Text received : {0}", data);
// Echo the data back to the client.
msg = Encoding.ASCII.GetBytes(System.AppDomain.CurrentDomain.BaseDirectory);
handler.Send(msg);
//break;
}
if (data.Equals("files"))
{
// Show the data on the console.
Console.WriteLine("Text received : {0}", data);
String files = "";
string[] fileEntries = Directory.GetFiles(System.AppDomain.CurrentDomain.BaseDirectory);
foreach (string fileName in fileEntries)
files += ProcessFile(fileName);
// Echo the data back to the client.
msg = Encoding.ASCII.GetBytes(files);
handler.Send(msg);
//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();
}
public static String ProcessFile(string path)
{
return path += "\n\n" + path;
}
public static void ProcessDirectory(string targetDirectory)
{
// Process the list of files found in the directory.
string[] fileEntries = Directory.GetFiles(targetDirectory);
foreach (string fileName in fileEntries)
ProcessFile(fileName);
// Recurse into subdirectories of this directory.
string[] subdirectoryEntries = Directory.GetDirectories(targetDirectory);
foreach (string subdirectory in subdirectoryEntries)
ProcessDirectory(subdirectory);
}
public static int Main(String[] args)
{
StartListening();
return 0;
}
}

c# asynchronous socket client/server hangs on server response

I've been playing with some c# socket code that I found at MSDN (original server code and client code) and I've run into a problem that I don't understand. First, here is my socket server code:
using System;
using System.Collections;
using System.Collections.Generic;
using System.Net;
using System.Net.Sockets;
using System.Text;
using System.Threading;
namespace AsyncSocketServerTest
{
class Program
{
public class StateObject
{
public Socket socket = null;
public const int BufferSize = 1024;
public byte[] buffer = new byte[BufferSize];
public List<byte> bytes = new List<byte>();
}
public static ManualResetEvent allDone = new ManualResetEvent(false);
private const string ipAdd = "127.0.0.1";
public static void StartListening()
{
byte[] bytes = new byte[1024];
IPAddress ipAddress = IPAddress.Parse(ipAdd);
IPEndPoint localEndPoint = new IPEndPoint(ipAddress, 25981);
Socket listener = new Socket(AddressFamily.InterNetwork, SocketType.Stream, ProtocolType.Tcp);
try
{
listener.Bind(localEndPoint);
listener.Listen(100);
while (true)
{
allDone.Reset();
listener.BeginAccept(new AsyncCallback(AcceptCallback), listener);
allDone.WaitOne();
}
}
catch (Exception e)
{
Console.WriteLine(e.ToString());
}
Console.WriteLine("\nPress ENTER to continue...");
Console.Read();
}
public static void AcceptCallback(IAsyncResult ar)
{
allDone.Set();
Socket listener = (Socket)ar.AsyncState;
Socket handler = listener.EndAccept(ar);
StateObject state = new StateObject();
state.socket = handler;
handler.BeginReceive(state.buffer, 0, StateObject.BufferSize, 0, new AsyncCallback(ReadCallback), state);
}
public static void ReadCallback(IAsyncResult ar)
{
Console.WriteLine("Inside ReadCallback()...");
// retrieve the state object and the handler socket from the asynchronous state object
StateObject state = (StateObject)ar.AsyncState;
Socket socket = state.socket;
// read data from the client socket
int bytesRead = socket.EndReceive(ar);
if (bytesRead > 0)
{
// there might be more data, so store the data received so far
for (int bufferIndex = 0; bufferIndex < bytesRead; bufferIndex++)
{
state.bytes.Add(state.buffer[bufferIndex]);
}
socket.BeginReceive(state.buffer, 0, StateObject.BufferSize, 0, new AsyncCallback(ReadCallback), state);
}
else
{
if (state.bytes.Count > 0)
{
// All the data has been read from the client; display it on the console.
byte[] bytesReceived = state.bytes.ToArray();
Console.WriteLine("Received {0} bytes from client...", bytesReceived.Length.ToString());
}
// generate a 50 byte response to send back to the client
Random r = new Random();
byte[] responseToSend = new byte[50];
r.NextBytes(responseToSend);
// *** THIS APPEARS TO BE CAUSING A PROBLEM ***
// send the response back to client
SendBytes(socket, responseToSend);
// ********************************************
// edit - commented out; the socket shouldn't be closed before the response is sent back to the client asynchronously
//socket.Close();
}
}
private static void SendBytes(Socket client, byte[] bytesToSend)
{
client.BeginSend(bytesToSend, 0, bytesToSend.Length, 0, new AsyncCallback(SendCallback), client);
}
private static void SendCallback(IAsyncResult ar)
{
try
{
Socket handler = (Socket)ar.AsyncState;
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());
}
}
static void Main(string[] args)
{
StartListening();
Console.ReadKey();
}
}
}
And now for the client code:
using System;
using System.Collections.Generic;
using System.IO;
using System.Net;
using System.Net.Sockets;
using System.Text;
using System.Threading;
namespace AsyncSocketClientTest
{
class Program
{
public class StateObject
{
public Socket socket = null;
public const int BufferSize = 1024;
public byte[] buffer = new byte[BufferSize];
public List<byte> bytes = new List<byte>();
}
private const string ipAdd = "127.0.0.1";
// ManualResetEvent instances signal completion
private static ManualResetEvent connectDone = new ManualResetEvent(false);
private static ManualResetEvent sendDone = new ManualResetEvent(false);
private static ManualResetEvent receiveDone = new ManualResetEvent(false);
private static void StartClient()
{
try
{
IPAddress ipAddress = IPAddress.Parse(ipAdd);
IPEndPoint remoteEndPoint = new IPEndPoint(ipAddress, 25981);
Socket client = new Socket(AddressFamily.InterNetwork, SocketType.Stream, ProtocolType.Tcp);
client.BeginConnect(remoteEndPoint, new AsyncCallback(ConnectCallback), client);
connectDone.WaitOne();
// generate 100 random bytes to send to the server
Random r = new Random();
byte[] buffer = new byte[100];
r.NextBytes(buffer);
// send data to the server
SendBytes(client, buffer);
sendDone.WaitOne();
// *** THIS APPEARS TO BE CAUSING A PROBLEM ***
// receive the response from the remote host
ReceiveBytes(client);
receiveDone.WaitOne();
// ********************************************
// release the socket
client.Shutdown(SocketShutdown.Both);
client.Close();
}
catch (Exception e)
{
Console.WriteLine(e.ToString());
}
}
private static void ConnectCallback(IAsyncResult ar)
{
try
{
// retrieve the socket from the state object
Socket client = (Socket)ar.AsyncState;
// complete the connection
client.EndConnect(ar);
Console.WriteLine("Socket connected to {0}", client.RemoteEndPoint.ToString());
// signal that the connection has been made
connectDone.Set();
}
catch (SocketException sockEx)
{
// if the server isn't running, we're going to get a socket exception here...
Console.WriteLine(sockEx.Message);
}
catch (Exception e)
{
Console.WriteLine(e.ToString());
}
}
private static void ReceiveBytes(Socket client)
{
Console.WriteLine("Inside ReceiveBytes()...");
try
{
// create the state object
StateObject state = new StateObject();
state.socket = client;
// begin receiving data from the remote device
client.BeginReceive(state.buffer, 0, StateObject.BufferSize, 0, new AsyncCallback(ReceiveCallback), state);
}
catch (Exception e)
{
Console.WriteLine(e.ToString());
}
}
private static void ReceiveCallback(IAsyncResult ar)
{
Console.WriteLine("Inside ReceiveCallback()...");
try
{
// Retrieve the state object and the client socket from the asynchronous state object
StateObject state = (StateObject)ar.AsyncState;
Socket client = state.socket;
// Read data from the remote host
int bytesRead = client.EndReceive(ar);
if (bytesRead > 0)
{
// there might be more data, so store the data received so far
for (int bufferIndex = 0; bufferIndex < bytesRead; bufferIndex++)
{
state.bytes.Add(state.buffer[bufferIndex]);
}
client.BeginReceive(state.buffer, 0, StateObject.BufferSize, 0, new AsyncCallback(ReceiveCallback), state);
}
else
{
if (state.bytes.Count > 0)
{
// All the data has been read from the client; display it on the console.
byte[] bytesReceived = state.bytes.ToArray();
Console.WriteLine("Read {0} bytes from socket...", bytesReceived.Length.ToString());
}
// Signal that all bytes have been received
receiveDone.Set();
}
}
catch (Exception e)
{
Console.WriteLine(e.ToString());
}
}
private static void SendBytes(Socket client, byte[] bytesToSend)
{
// Begin sending the data to the remote device
client.BeginSend(bytesToSend, 0, bytesToSend.Length, 0, new AsyncCallback(SendCallback), client);
}
private static void SendCallback(IAsyncResult ar)
{
try
{
// retrieve the socket from the state object
Socket client = (Socket)ar.AsyncState;
// complete sending the data to the remote device
int bytesSent = client.EndSend(ar);
Console.WriteLine("Sent {0} bytes to server.", bytesSent);
// signal that all bytes have been sent
sendDone.Set();
}
catch (Exception e)
{
Console.WriteLine(e.ToString());
}
}
static void Main(string[] args)
{
StartClient();
}
}
}
If I comment out the code in the client that receives the response back from the server as well as the code in the server that attempts to send the response to the client, then things appear to be working as you would expect (i.e., the client connects to the server, sends data and the server receives the data properly). When I uncomment these sections of the code, however, I'm seeing some behavior that I don't understand. In this case, I see the client connect to the server and send data to it. On the server side, the code appears to hang inside ReadCallback(). To better illustrate this, when the code sections I mentioned previously are commented out, I see this:
Client output:
Socket connected to 127.0.0.1:25981
Sent 100 bytes to server.
Server output:
Waiting for a connection...
Waiting for a connection...
Inside ReadCallback()...
Inside ReadCallback()...
Received 100 bytes from client...
As you can see from this output, when the server receives the 100 bytes of client data, I see two calls to ReadCallback(). So now I uncomment the aforementioned code and run it again. This time, I see:
Client output:
Socket connected to 127.0.0.1:25981
Sent 100 bytes to server.
Inside ReceiveBytes()...
Server output:
Waiting for a connection...
Waiting for a connection...
Inside ReadCallback()...
This time, my client sends 100 bytes of data to the server, sets the sendDone ManualResetEvent and then goes into ReceiveBytes(). On the server side, I see a single call to ReadCallback() and nothing else. That leads me to believe that the server didn't properly finish reading the data from the client although I'm not sure why. What am I missing?
This doesn't really answer your exact question but may I suggest an alternate way to go about this? For me threads are a bit easier to understand and the code looks a bit cleaner:
Server
using System;
using System.Collections.Generic;
using System.Linq;
using System.Net;
using System.Net.Sockets;
using System.Text;
using System.Threading;
using System.Threading.Tasks;
namespace ConsoleApplication2 {
class Program {
static void Main(string[] args) {
ServerWorkThread objThread = new ServerWorkThread();
while(true) {
objThread.HandleConnection(objThread.mySocket.Accept());
}
}
}
public class ServerWorkThread {
public Socket mySocket;
public ServerWorkThread() {
IPEndPoint objEnpoint = new IPEndPoint(IPAddress.Parse("***.***.***.***"), 8888);
mySocket = new Socket(AddressFamily.InterNetwork, SocketType.Stream, ProtocolType.Tcp);
mySocket.Bind(objEnpoint);
mySocket.Listen(100);
}
public void HandleConnection(Socket iIncomingSocket) {
Thread worker = new Thread(this.RecieveAndSend);
worker.Start(iIncomingSocket);
worker.Join();
}
public void RecieveAndSend(object iIncoming) {
Socket objSocket = (Socket)iIncoming;
byte[] bytes = new byte[1024];
int bytesRecieved = objSocket.Receive(bytes);
string strReceived = System.Text.Encoding.ASCII.GetString(bytes, 0, bytesRecieved);
Console.WriteLine("Received from client: " + strReceived);
Console.WriteLine("Sending acknowledgement to client");
string strSend = ("Command of: " + strReceived + " was processed successfully");
objSocket.Send(System.Text.Encoding.ASCII.GetBytes(strSend));
objSocket.Close();
}
}
}
Client:
using System;
using System.Collections.Generic;
using System.Linq;
using System.Net;
using System.Net.Sockets;
using System.Text;
using System.Threading;
using System.Threading.Tasks;
namespace Client {
class Program {
static void Main(string[] args) {
ClientWorkThread thread1 = new ClientWorkThread("I am thread 1");
thread1.SendCommand();
ClientWorkThread thread2 = new ClientWorkThread("I am thread 2");
thread2.SendCommand();
ClientWorkThread thread3 = new ClientWorkThread("I am thread 3");
thread3.SendCommand();
Console.Read();
}
}
public class ClientWorkThread {
private Socket pSocket;
private string command;
public ClientWorkThread(string iCommand) {
IPEndPoint objEnpoint = new IPEndPoint(IPAddress.Parse("***.***.***.***"), 8888);
pSocket = new Socket(AddressFamily.InterNetwork, SocketType.Stream, ProtocolType.Tcp);
pSocket.Connect(objEnpoint);
command = iCommand;
}
public void SendCommand() {
Thread worker = new Thread(this.Send);
worker.Start(pSocket);
}
public void Send(object iSending) {
Socket objSocket = (Socket)iSending;
objSocket.Send(System.Text.Encoding.ASCII.GetBytes(command + " now DO WORK "));
Console.WriteLine("Sending: " + command + " now DO WORK ");
byte[] bytes = new byte[1024];
int bytesRecieved = objSocket.Receive(bytes);
string strReceived = System.Text.Encoding.ASCII.GetString(bytes, 0, bytesRecieved);
Console.WriteLine("Received from server: " + strReceived);
objSocket.Close();
}
}
}
Server output:
Received from client: I am thread 1 now DO WORK
Sending acknowledgement to client
Received from client: I am thread 2 now DO WORK
Sending acknowledgement to client
Received from client: I am thread 3 now DO WORK
Sending acknowledgement to client
Client output:
Sending: I am thread 2 now DO WORK
Sending: I am thread 3 now DO WORK
Received from server: Command of: I am thread 2 now DO WORK was processed successfully
Received from server: Command of: I am thread 3 now DO WORK was processed successfully
Sending: I am thread 1 now DO WORK
Received from server: Command of: I am thread 1 now DO WORK was processed successfully
You could also use thread.Join() to have them finish executing in order.

C#. Multicast client-server application

I try to create simple console application 'Chat' using UDP protocol and multicasting. I can only send message from server to client. Server code:
using System;
using System.Text;
using System.Net.Sockets;
using System.Net;
namespace Server
{
class Program
{
static void Main(string[] args)
{
// Create object UdpClient
UdpClient udpClient = new UdpClient();
// IPAddress of group
IPAddress multicastaddress = IPAddress.Parse("224.192.168.255");
try
{
// Join group
udpClient.JoinMulticastGroup(multicastaddress);
}
catch (Exception e)
{
Console.WriteLine("Error: " + e.ToString());
}
// Create object IPEndPoint
IPEndPoint remoteep = new IPEndPoint(multicastaddress, 2345);
// Print message
Console.WriteLine("Server is running ...\n\nEnter message: ");
// Data in Byte []
Byte[] buffer = Encoding.Unicode.GetBytes(Console.ReadLine ());
try
{
// Send data using IPEndPoint
udpClient.Send(buffer, buffer.Length, remoteep);
}
catch (Exception e)
{
Console.WriteLine("Error: " + e.ToString ());
}
// Leave the group
udpClient.DropMulticastGroup(multicastaddress);
// Close connection
udpClient.Close();
}
}
}
Client:
using System;
using System.Text;
using System.Net.Sockets;
using System.Net;
namespace Client
{
class Program
{
static void Main(string[] args)
{
// Create UDP client
UdpClient client = new UdpClient();
// Create new IPEndPoint
IPEndPoint localEp = new IPEndPoint(IPAddress.Any, 2345);
// Set socket options
client.Client.SetSocketOption(SocketOptionLevel.Socket, SocketOptionName.ReuseAddress, true);
// Bind to IPEndPoint
client.Client.Bind(localEp);
// IP address
IPAddress multicastaddress = IPAddress.Parse("224.192.168.255");
try
{
// Join group
client.JoinMulticastGroup(multicastaddress);
}
catch (Exception e)
{
Console.WriteLine("Error: " + e.ToString());
}
Console.WriteLine("Client is running ...\n\n");
// Receive data
Byte[] data = client.Receive(ref localEp);
string strData = Encoding.Unicode.GetString(data);
Console.WriteLine("Server: " + strData);
// Leave the group
client.DropMulticastGroup(multicastaddress);
// Close connection
client.Close();
}
}
}
How can I send message from server and receive the response from client, after this send next message and receive response from client etc.? Is it possible to implement this using UdpClient class and multicasting or not?
Thank you very much!

Categories

Resources