SSH into machine then connect TCP socket - c#

I am able to:
ssh -p 8811 myuser#74.xxx.xxx.xxx
Then from within that machine, can run a program that successfully establishes socket connection at 10.xx.xxx.xxx on port 32060.
I am trying to convert it to a local C# program that does the ssh + socket connection without having to keep the ssh open on my terminal, so I can just run the program.
It is able to successfully ssh in, then ping the 10.xx.xxx.xxx address, but cannot establish the socket connection. Am I missing a step?
using (var client = new SshClient("74.xxx.xxx.xxx", 8811, "myuser", privatekey))
{
client.Connect();
string host = "10.xx.xxx.xxx";
int port = 32060;
if (client.IsConnected)
{
Console.WriteLine("ssh connected");
SshCommand cmd = client.CreateCommand($"ping -c 3 {host}");
cmd.Execute();
Console.WriteLine(cmd.Result); // successfully pings 10.xx.xxx.xxx
TcpClient tcpClient = new TcpClient();
tcpClient.Connect(new IPEndPoint(IPAddress.Parse(host), port));
Console.WriteLine("tcp connected"); // fails, times out when trying 10.xx.xxx.xxx:32060
}
client.Disconnect();
}

I was able to get this to work using a package called Chilkat socket.UseSsh(): https://www.chilkatsoft.com/refdoc/csSocketRef.html#method91
string sshUsername = "myuser";
string sshHostname = "74.xxx.xxx.xxx";
int sshPort = 8811;
string socketHostname = "10.xx.xxx.xxx";
int socketPort = 32060;
// === SSH ===
Chilkat.Ssh ssh = new Chilkat.Ssh();
Chilkat.SshKey sshkey = new Chilkat.SshKey();
sshkey.FromOpenSshPrivateKey(#"xxx");
bool success = ssh.Connect(sshHostname, sshPort);
if (success != true)
{
Console.WriteLine(ssh.LastErrorText);
return;
}
success = ssh.AuthenticatePk(sshUsername, sshkey);
if (success != true)
{
Console.WriteLine(ssh.LastErrorText);
return;
}
// === Socket ===
Chilkat.Socket socket = new Chilkat.Socket();
success = socket.UseSsh(ssh);
if (success != true)
{
Console.WriteLine(socket.LastErrorText);
return;
}
bool useTls = false;
int maxWaitMillisec = 20000;
success = socket.Connect(socketHostname, socketPort, useTls, maxWaitMillisec);
if (success != true)
{
Console.WriteLine(socket.LastErrorText);
return;
}

Related

Sending asynchronous message from server to client

I am writing program to solve the dining philosophers problem without a server. It should work by message passing. My application should run 5 times and then connect to each other and solve the problem by themselves. I put a server side and client side in each app, and I gave them a port number. This image will show what i am talking about:
https://www.photobox.co.uk/my/photo/full?photo_id=500223105218
All I want is sending messages between client sides and server sides.
But I have an error in sending message asynchronously from server side by socket handler.(mentioned it below)
I searched about that but could not find any code similar, so how can I send messages directly from server side to client side?
And, how is my idea? is that right? or it is wrong.
This is part of my code which works well:
String status = "Thinking";
Boolean right = false;
Boolean left = false;
// Receiving byte array
byte[] bytes = new byte[1024];
SocketPermission permission;
Socket sListener;
Socket sListener1;
Socket sListener2;
Socket sListener3;
Socket sListener4;
Socket handler1;
Socket handler2;
Socket handler3;
Socket handler4;
Socket handler5;
Socket senderSock;
Socket senderSock1;
Socket senderSock2;
Socket senderSock3;
Socket senderSock4;
public Form1()
{
InitializeComponent();
}
//start button
private void button1_Click(object sender, EventArgs e)
{
try
{
IPEndPoint ipEndPoint=null;
IPEndPoint ipEndPoint1=null;
IPEndPoint ipEndPoint2 = null;
IPEndPoint ipEndPoint3 = null;
IPEndPoint ipEndPoint4 = null;
// Creates one SocketPermission object for access restrictions
permission = new SocketPermission(
NetworkAccess.Accept, // Allowed to accept connections
TransportType.Tcp, // Defines transport types
"", // The IP addresses of local host
SocketPermission.AllPorts // Specifies all ports
);
// Listening Socket object
sListener = null;
sListener1 = null;
sListener2 = null;
sListener3 = null;
sListener4 = null;
// Ensures the code to have permission to access a Socket
permission.Demand();
// Resolves a host name to an IPHostEntry instance
IPHostEntry ipHost = Dns.GetHostEntry("");
// Gets first IP address associated with a localhost
IPAddress ipAddr = ipHost.AddressList[0];
// Creates a network endpoint
if (Sport.Text == "1000")
{
ipEndPoint = new IPEndPoint(ipAddr, Convert.ToInt32(Sport.Text));
}else if (Sport.Text == "1001")
{
ipEndPoint1 = new IPEndPoint(ipAddr, Convert.ToInt32(Sport.Text));
}
else if (Sport.Text == "1002")
{
ipEndPoint2 = new IPEndPoint(ipAddr, Convert.ToInt32(Sport.Text));
}
else if (Sport.Text == "1003")
{
ipEndPoint3 = new IPEndPoint(ipAddr, Convert.ToInt32(Sport.Text));
}
else if (Sport.Text == "1004")
{
ipEndPoint4 = new IPEndPoint(ipAddr, Convert.ToInt32(Sport.Text));
}
// Associates a Socket with a local endpoint
if (Sport.Text == "1000")
{
// Create one Socket object to listen the incoming connection
sListener = new Socket(
ipAddr.AddressFamily,
SocketType.Stream,
ProtocolType.Tcp
);
sListener.Bind(ipEndPoint);
sListener.Listen(10);
}else if(Sport.Text == "1001")
{
sListener1 = new Socket(
ipAddr.AddressFamily,
SocketType.Stream,
ProtocolType.Tcp
);
sListener1.Bind(ipEndPoint1);
sListener1.Listen(10);
}
else if (Sport.Text == "1002")
{
sListener2 = new Socket(
ipAddr.AddressFamily,
SocketType.Stream,
ProtocolType.Tcp
);
sListener2.Bind(ipEndPoint2);
sListener2.Listen(10);
}
else if (Sport.Text == "1003")
{
sListener3 = new Socket(
ipAddr.AddressFamily,
SocketType.Stream,
ProtocolType.Tcp
);
sListener3.Bind(ipEndPoint3);
sListener3.Listen(10);
}
else if (Sport.Text == "1004")
{
sListener4 = new Socket(
ipAddr.AddressFamily,
SocketType.Stream,
ProtocolType.Tcp
);
sListener4.Bind(ipEndPoint4);
sListener4.Listen(10);
}
label3.Text = "Server started.";
statusLabel.Text = "READY";
button1.Enabled = false;
}
catch (Exception exc) { MessageBox.Show(exc.ToString()); }
}
//connect button
private void button2_Click(object sender, EventArgs e)
{
try
{
IPEndPoint ipEndPoint = null;
IPEndPoint ipEndPoint1 = null;
IPEndPoint ipEndPoint2 = null;
IPEndPoint ipEndPoint3 = null;
IPEndPoint ipEndPoint4 = null;
// Create one SocketPermission for socket access restrictions
SocketPermission permission = new SocketPermission(
NetworkAccess.Connect, // Connection permission
TransportType.Tcp, // Defines transport types
"", // Gets the IP addresses
SocketPermission.AllPorts // All ports
);
// Ensures the code to have permission to access a Socket
permission.Demand();
// Resolves a host name to an IPHostEntry instance
IPHostEntry ipHost = Dns.GetHostEntry("");
// Gets first IP address associated with a localhost
IPAddress ipAddr = ipHost.AddressList[0];
// Creates a network endpoint
if (Cport.Text == "1000")
{
ipEndPoint = new IPEndPoint(ipAddr, Convert.ToInt32(Cport.Text));
}else if (Cport.Text == "1001")
{
ipEndPoint1 = new IPEndPoint(ipAddr, Convert.ToInt32(Cport.Text));
}
else if (Cport.Text == "1002")
{
ipEndPoint2 = new IPEndPoint(ipAddr, Convert.ToInt32(Cport.Text));
}
else if (Cport.Text == "1003")
{
ipEndPoint3 = new IPEndPoint(ipAddr, Convert.ToInt32(Cport.Text));
}
else if (Cport.Text == "1004")
{
ipEndPoint4 = new IPEndPoint(ipAddr, Convert.ToInt32(Cport.Text));
}
if (Cport.Text == "1000")//A
{
// Create one Socket object to setup Tcp connection
senderSock = new Socket(
ipAddr.AddressFamily,// Specifies the addressing scheme
SocketType.Stream, // The type of socket
ProtocolType.Tcp // Specifies the protocols
);
senderSock.NoDelay = false; // Using the Nagle algorithm
// Establishes a connection to a remote host
senderSock.Connect(ipEndPoint);
statusLabel.Text = "Socket connected to " + senderSock.RemoteEndPoint.ToString();
}
else if (Cport.Text == "1001")//B
{
senderSock1 = new Socket(
ipAddr.AddressFamily,
SocketType.Stream,
ProtocolType.Tcp
);
senderSock1.NoDelay = false;
senderSock1.Connect(ipEndPoint1);
statusLabel.Text = "Socket connected to " + senderSock1.RemoteEndPoint.ToString();
}
else if (Cport.Text == "1002")//C
{
senderSock2 = new Socket(
ipAddr.AddressFamily,
SocketType.Stream,
ProtocolType.Tcp
);
senderSock2.NoDelay = false;
senderSock2.Connect(ipEndPoint2);
statusLabel.Text = "Socket connected to " + senderSock2.RemoteEndPoint.ToString();
}
else if (Cport.Text == "1003")//D
{
senderSock3 = new Socket(
ipAddr.AddressFamily,
SocketType.Stream,
ProtocolType.Tcp
);
senderSock3.NoDelay = false;
senderSock3.Connect(ipEndPoint3);
statusLabel.Text = "Socket connected to " + senderSock3.RemoteEndPoint.ToString();
}
else if (Cport.Text == "1004")//E
{
senderSock4 = new Socket(
ipAddr.AddressFamily,
SocketType.Stream,
ProtocolType.Tcp
);
senderSock4.NoDelay = false;
senderSock4.Connect(ipEndPoint4);
statusLabel.Text = "Socket connected to " + senderSock4.RemoteEndPoint.ToString();
}
button2.Enabled = false;
}
catch (Exception exc) { MessageBox.Show(exc.ToString()); }
label3.Text = "wait...";
Thread.Sleep(4000);
send_st();
}
And here is my code where I get an Error in "Send(handler1, status);"
The error is: "Object reference not set to an instance of an object"
//send status from clnt to server
public void sendCToS(String str)
{
try
{
// Sending message
//<Client Quit> is the sign for end of data
byte[] msg = Encoding.Unicode.GetBytes(str + "<Client Quit>");
// Sends data to a connected Socket.
//send status from client to server
int bytesSend = senderSock.Send(msg);//receiver server tasmim giri va response send mikone
}
catch (Exception exc) { MessageBox.Show(exc.ToString()); }
}
//it send hungry status from both to both!
public void send_st()
{
// Resolves a host name to an IPHostEntry instance
IPHostEntry ipHost = Dns.GetHostEntry("");
// Gets first IP address associated with a localhost
IPAddress ipAddr = ipHost.AddressList[0];
Random rnd = new Random();
int delay = rnd.Next(2000, 5000);
while (true)
{
//System.Threading.Thread.Sleep(2000);
statusLabel.Text = status;
statusLabel.ForeColor = System.Drawing.Color.Blue;
Thread.Sleep(delay);
if (Sport.Text == "1000")//A
{
status = "hungry";
statusLabel.Text = "HUNGRY";
statusLabel.ForeColor = System.Drawing.Color.Red;
//send status from server to clint
Send(handler1, status);
//send status from clnt to server
sendCToS(status);
label3.Text = "status Sent to left and right";
}
else if (Sport.Text == "1001")//B
{
Thread.Sleep(2000);
status = "hungry";
statusLabel.Text = "HUNGRY";
statusLabel.ForeColor = System.Drawing.Color.Red;
//send status from server to clint
Send(handler2, status);
//send status from clnt to server
sendCToS(status);
label3.Text = "status Sent to left and right";
}
else if (Sport.Text == "1002")//C
{
status = "hungry";
statusLabel.Text = "HUNGRY";
statusLabel.ForeColor = System.Drawing.Color.Red;
//send status from server to clint
Send(handler3, status);
//send status from clnt to server
sendCToS(status);
label3.Text = "status Sent to left and right";
}
else if (Sport.Text == "1003")//D
{
Thread.Sleep(2000);
status = "hungry";
statusLabel.Text = "HUNGRY";
statusLabel.ForeColor = System.Drawing.Color.Red;
//send status from server to clint
Send(handler4, status);
//send status from clnt to server
sendCToS(status);
label3.Text = "status Sent to left and right";
}
else if (Sport.Text == "1004")//E
{
Thread.Sleep(3000);
status = "hungry";
statusLabel.Text = "HUNGRY";
statusLabel.ForeColor = System.Drawing.Color.Red;
//send status from server to clint
Send(handler5, status);
//send status from clnt to server
sendCToS(status);
label3.Text = "status Sent to left and right";
}
}
}
//server side
// Thread signal.
public static ManualResetEvent allDone = new ManualResetEvent(false);
public void AcceptCallback(IAsyncResult ar)
{
Socket listener = null;
// A new Socket to handle remote host communication
Socket handler = null;
try
{
// Receiving byte array
byte[] buffer = new byte[1024];
// Get Listening Socket object
listener = (Socket)ar.AsyncState;
// Create a new socket
handler = listener.EndAccept(ar);
// Using the Nagle algorithm
handler.NoDelay = false;
StateObject state = new StateObject();
// Begins to asynchronously receive data
handler.BeginReceive(
buffer, // An array of type Byt for received data
0, // The zero-based position in the buffer
buffer.Length, // The number of bytes to receive
0,// Specifies send and receive behaviors
new AsyncCallback(ReceiveCallback),//An AsyncCallback delegate
state // Specifies infomation for receive operation
);
}
catch (Exception exc) { MessageBox.Show(exc.ToString()); }
}
public void ReceiveCallback(IAsyncResult ar)
{
String response = "ok";
try
{
// 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);
// Received message
string content = string.Empty;
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("<Client Quit>") > -1)
{
// All the data has been read from the client
label3.Text = content;
}
else {
// Not all data received. Get more.
handler.BeginReceive(state.buffer, 0,StateObject.BufferSize, 0,
new AsyncCallback(ReceiveCallback), state);
}
And this is the rest of the server side functions:
//func for echo back to client
private 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);
}
public void SendCallback(IAsyncResult ar)
{
try
{
// A Socket which has sent the data to remote host
Socket handler = (Socket)ar.AsyncState;
// The number of bytes sent to the Socket
int bytesSend = handler.EndSend(ar);
label3.Text = "Sent {0} bytes to Client" + bytesSend;
}
catch (Exception exc) { MessageBox.Show(exc.ToString()); }
I belive the problem is with this line:
senderSock.Send(msg);
You never instantiated the senderSock, you only declared it.
try this:
senderSock= new Socket(AddressFamily.InterNetwork, SocketType.Stream, ProtocolType.Tcp);
senderSock.Send(msg);

TCP Connexion between Xamarin.Android and SDL_Net

I'm trying to establish a TCP connexion between a C# Xamarin Android app and a C++ app on a Raspberry pi.
On the C# client side, I'm using the TcpClient client from System.Net.Sockets :
// C#
static public bool Connect(string IP, string port)
{
bool _connected = false;
try
{
client = new TcpClient();
IPAddress _ip = IPAddress.Parse(IP);
int _port = int.Parse(port);
client.Connect(_ip, _port);
_connected = true;
}
catch
{
_connected = false;
}
return _connected;
}
This is a pretty straight forward use of the TcpClient class as you can see.
On the server side, using SDL_Net (1.2), here is my socket init :
// C++
string mNet::Resolve()
{
socketSet = SDLNet_AllocSocketSet(2);
if(socketSet == NULL)
return "Could not allocate socket set : " + string(SDLNet_GetError());
if(SDLNet_ResolveHost(&serverIP, NULL, Prefs::NET_PORT) == -1)
return "Could not resolve server host : " + string(SDLNet_GetError());
serverSocket = SDLNet_TCP_Open(&serverIP);
if(!serverSocket)
return "Could not create server socket : " + string(SDLNet_GetError());
SDLNet_TCP_AddSocket(socketSet, serverSocket);
return "OK";
}
and here is a dummy listener for testing :
// C++
void mNet::Update()
{
int serverSocketActivity = SDLNet_SocketReady(serverSocket);
if (serverSocketActivity != 0)
{
if(!ClientConnected) // new connection
{
clientSocket = SDLNet_TCP_Accept(serverSocket);
SDLNet_TCP_AddSocket(socketSet, clientSocket);
ClientConnected = true;
SendToClient("1");
Logger::Log("Client connected !");
}
else // server busy
{
SendToClient("0", true);
Logger::Log("Client refused !");
}
}
}
I get no error from the initialization, and when I run a netstat -an | grep tcp command on the raspberry, I can see the port i'm using (1234) opened.
But when I try to connect from the android emulator, it seems that nothing is happening server side (no socket activity).
IP & ports are matching.
I'm not really used to networking, so is there something I'm doing wrong here ?
Additional info :
Targeting Android 6
RaspberryPi is running UbunutuMate
Networking C# class : https://github.com/arqtiq/RemotePlayerPi/blob/master/App/Network.cs
Networking C++ class : https://github.com/arqtiq/RemotePlayerPi/blob/master/Server/src/mNet.cpp
Thanks !

C# TCP Chat-Server: Connection only works one way

I've got a generic TCP Client and TCP Listener setup on my main laptop and my other laptop. The client and listener are their own separate programs, so I've had a client and server running on both laptops to try and get a simple instant messenger going.
The client and server will happily communicate with each other if both programs are executed on the same laptop. This is true for both my main and other laptop.
My main laptop's client will happily send messages to my other laptop, and the other laptop will gracefully receive messages from my main laptop.
However, when my other laptop's client sends a message to my main laptop's server it gets a timeout-related, communication-failed type of error. It just doesn't send the message.
Error message (caught by try-catch); "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 {my IP:port number}."
I'm getting the IP and port numbers correct, so rule that out.
There's no firewall business because the other laptop doesn't care at all about receiving messages from my main laptop.
I've also tried random port numbers and made sure that the client on my main laptop is connecting over the same port number that my other laptop's sever is listening on (or accepting messages from).
So why isn't my other laptop successfully sending messages to my main laptop?
The client asks for the user to enter an IP and then a port number. It then waits for the user to enter a message, then connects and sends that message to the IP via the given port number.
The server asks the user to enter a port number and prints messages received through that port.
Here's the code for the client program;
static void Main(string[] args)
{
string IP = localIPAddress();
Console.WriteLine("Your IP: " + IP); //provides IP number
Console.Write("Enter IP to connect to: ");
string connectToIP = Console.ReadLine();
if (connectToIP == "self")
{
connectToIP = localIPAddress();
// if I want to test both on the same computer
}
Console.WriteLine("\nEnter port number: ");
int portNo = int.Parse(Console.ReadLine());
while (true)
{
string message = Console.ReadLine();
try
{
// connection doesn't begin until ReadLine is done
request(connectToIP, portNo, message);
}
catch (Exception e)
{
Console.WriteLine(e.Message);
}
}
}
public static string localIPAddress()
{
IPHostEntry host;
string localIP = "?";
host = Dns.GetHostEntry(Dns.GetHostName());
foreach (IPAddress ip in host.AddressList)
{
if (ip.AddressFamily == AddressFamily.InterNetwork)
{
localIP = ip.ToString();
}
}
return localIP;
}
static void request(string address, int port, string message)
{
TcpClient client = new TcpClient();
client.SendTimeout = 1000;
client.ReceiveTimeout = 1000;
try
{
client.Connect(address, port);
StreamWriter sw = new StreamWriter(client.GetStream());
sw.WriteLine(message);
sw.Flush();
sw.Close();
}
catch (Exception a)
{
Console.ForegroundColor = ConsoleColor.Red;
Console.WriteLine(a.Message.ToString());
Console.ResetColor();
}
}
Here's the code for the server;
static void Main(string[] args)
{
Console.WriteLine("Your IP: " + localIPAddress());
Console.Write("Enter port number you're receiving from: ");
int portNo = int.Parse(Console.ReadLine());
TcpListener listener = new TcpListener(IPAddress.Any, portNo);
Socket connection;
NetworkStream socketStream;
listener.Start();
while (true)
{
connection = listener.AcceptSocket();
connection.SendTimeout = 1000;
connection.ReceiveTimeout = 1000;
socketStream = new NetworkStream(connection);
try
{
respond(socketStream);
}
catch(Exception e)
{
Console.WriteLine(e.Message);
}
finally
{
socketStream.Close();
connection.Close();
}
}
}
public static string localIPAddress()
{
IPHostEntry host;
string localIP = "?";
host = Dns.GetHostEntry(Dns.GetHostName());
foreach (IPAddress ip in host.AddressList)
{
if (ip.AddressFamily == AddressFamily.InterNetwork)
{
localIP = ip.ToString();
}
}
return localIP;
}
static void respond(NetworkStream strm)
{
List<string> sentIn = new List<string>();
StreamReader sr = new StreamReader(strm);
while (sr.Peek() != -1)
sentIn.Add(sr.ReadLine());
sr.Close();
foreach (string s in sentIn)
{
Console.WriteLine(s);
}
}
Is there a problem with my code? There have been no Firewall-related messages when either laptop uses these programs.
It might be the sw.Flush() for the client, because that used to cause the sending process to freeze.
Thanks in advance. Once I get this problem sorted, I can start wondering how this can be used to make a multiplayer XNA game.
You might want to try making the timeouts a little longer (or remove them all together; they caused problems for me). Also, it's really a good idea to create a thread to receive messages while you handle the sending on the main thread.
Some notes:
You can use "loopback" or "127.0.0.1" if you'd like to connect to your local IP
if (connectToIP == "self")
{
connectToIP = localIPAddress();
// if I want to test both on the same computer
}
You really shouldn't connect, send a single message, and then disconnect, only to connect again.
Try something like this for the client:
using System.Threading;
static void Main(string[] args)
{
TcpClient client = new TcpClient();
Console.Write("IP: ");
string ip = Console.ReadLine();
Console.Write("Port: ");
int port = int.Parse(Console.ReadLine());
try
{
client.Connect(ip, port);
StreamWriter sw = new StreamWriter(client.GetStream());
sw.AutoFlush = true;
StreamReader sr = new StreamReader(client.GetStream());
Thread readThread = new Thread(() => readSocket(sr));
readThread.Start(); //Run readSocket() at the same time
string message = "";
while (message != "exit")
{
message = Console.ReadLine();
sw.WriteLine(message);
}
client.Close();
return;
}
catch (Exception e) { Console.WriteLine(e.ToString()); }
}
static void readSocket(StreamReader sr)
{
try
{
string message = "";
while ((message = sr.ReadLine()) != null)
{
Console.WriteLine(message);
}
}
catch (System.IO.IOException) { /*when we force close, this goes off, so ignore it*/ }
catch (Exception e)
{
Console.WriteLine(e.ToString());
}
}
Here's an example of the Server:
static void Main(string[] args)
{
Console.Write("Port: ");
int port = int.Parse(Console.ReadLine());
TcpListener server = new TcpListener(IPAddress.Any, port);
try
{
server.Start();
TcpClient client = server.AcceptTcpClient();
StreamWriter sw = new StreamWriter(client.GetStream());
sw.AutoFlush = true;
StreamReader sr = new StreamReader(client.GetStream());
Thread readThread = new Thread(() => readSocket(sr));
readThread.Start();
string message = "";
while (message != "exit")
{
message = Console.ReadLine();
sw.WriteLine(message);
}
client.Close();
return;
}
catch (Exception e) { Console.WriteLine(e.ToString()); }
}
static void readSocket(StreamReader sr)
{
try
{
string message = "";
while ((message = sr.ReadLine()) != null)
{
Console.WriteLine(message);
}
}
catch (System.IO.IOException) { /*when we force close, this goes off, so ignore it*/ }
catch (Exception e)
{
Console.WriteLine(e.ToString());
}
}
Here is the code for an Async server that forwards messages to all connected clients (If you were worried about not being able to share a port).
I'm trying to keep these examples simple, but it's probably a good idea to add more exception handling to all of them.
class Server
{
private int port;
private Socket serverSocket;
private List<StateObject> clientList;
private const int DEFAULT_PORT = 1338;
public Server()
{
this.port = 1338; //default port
serverSocket = new Socket(AddressFamily.InterNetwork, SocketType.Stream, ProtocolType.Tcp);
clientList = new List<StateObject>();
}
public Server(int port)
{
this.port = port;
serverSocket = new Socket(AddressFamily.InterNetwork, SocketType.Stream, ProtocolType.Tcp);
clientList = new List<StateObject>();
}
public void startListening(int port = DEFAULT_PORT)
{
this.port = port;
serverSocket.Bind(new IPEndPoint(IPAddress.Any, this.port));
serverSocket.Listen(1);
serverSocket.BeginAccept(new AsyncCallback(AcceptCallback), null);
}
private void AcceptCallback(IAsyncResult AR)
{
try
{
StateObject state = new StateObject();
state.workSocket = serverSocket.EndAccept(AR);
//Console.WriteLine("Client Connected");
clientList.Add(state);
state.workSocket.BeginReceive(state.buffer, 0, StateObject.BufferSize, SocketFlags.None, new AsyncCallback(ReceiveCallback), state);
serverSocket.BeginAccept(new AsyncCallback(AcceptCallback), null);
}
catch { }
}
private void ReceiveCallback(IAsyncResult AR)
{
StateObject state = (StateObject)AR.AsyncState;
Socket s = state.workSocket;
try
{
int received = s.EndReceive(AR);
if (received == 0)
return;
if (received > 0)
state.sb.Append(Encoding.ASCII.GetString(state.buffer, 0, received));
string content = state.sb.ToString();
if (content.IndexOf(Environment.NewLine) > -1)
{
//Console.WriteLine(content);
foreach (StateObject others in clientList)
if (others != state)
others.workSocket.Send(Encoding.ASCII.GetBytes(content.ToCharArray()));
state.sb.Clear();
}
Array.Clear(state.buffer, 0, StateObject.BufferSize);
s.BeginReceive(state.buffer, 0, StateObject.BufferSize, 0, new AsyncCallback(ReceiveCallback), state);
}
catch (Exception huh) {
s.Close();
s.Dispose();
//Console.WriteLine("Client Disconnected");
clientList.Remove(state);
return;
}
}
class StateObject
{
public Socket workSocket = null;
public const int BufferSize = 1024;
public byte[] buffer = new byte[BufferSize];
public StringBuilder sb = new StringBuilder();
}
}

TCP connection timeout error code _COMPlusExceptionCode -532462766

I am a Newbie to TCP/IP programming in c#, so I am DESPERATE for a solution to my current problem!
I have designed a C# Windows application running under Windows 7 with a Sqlserver 2005 database. My application is trying to send an HL7 record over a TCP/IP connection, to a Unix Lab. system machine.
I can get a connection ok, and send the HL7. BUT I cannot get ANY reply from the Lab. server! the connection times-out with error code 10060, as well as a _COMPlusExceptionCode value of -532462766.
Here is a sample of my c# 'Connect' methods:
buildSendHL7_TCPIP hl7Agent = new buildSendHL7_TCPIP();
// class 'buildSendHL7_TCPIP(); ' contains methods to build the HL7 segments, as well as methods to send and receive messages over the TCP connection
string strServerIPAddress = string.Empty;
Int32 intSocketNo = new Int32();
bool sentOK = false;
/***********************************/
/*Try send the HL7 to LIS-HORIZON...*/
/***********************************/
strServerIPAddress = "10.1.6.248";
intSocketNo = 5910;
sentOK = hl7Agent.SendHL7(strServerIPAddress, intSocketNo, strHL7_Record);
if (!sentOK)
{
_strUIMessage = "*Error* HL7 Message NOT sent to LIS!";
opsMessageBox mb = new opsMessageBox(this);
mb.ShowDialog();
mb.Close();
goto EndLabel;
}
Here are the methods I've created to build a TCP connection and send the HL7 to the LIS Server:
public bool SendHL7(string strIPAddress, Int32 intSocket, string hl7message)
{
/* send the complete HL7 message to the server...*/
int port = (int)intSocket;
IPAddress localAddr = IPAddress.Parse(strIPAddress);
try
{
// Add the leading & trailing character field-separator and CR LineFeed' t.
string llphl7message = null;
llphl7message = "|";
llphl7message += hl7message;
llphl7message += Convert.ToChar(28).ToString();
llphl7message += Convert.ToChar(13).ToString();
// Get the size of the message that we have to send.
Byte[] bytesToSend = Encoding.ASCII.GetBytes(llphl7message);
Byte[] bytesReceived = new Byte[256];
// Create a socket connection with the specified server and port.
Socket s = ConnectSocket(localAddr, port);
// If the socket could not get a connection, then return false.
if (s == null)
return false;
// Send message to the server.
s.Send(bytesToSend, bytesToSend.Length, 0);
// Receive the response back
int bytes = 0;
s.ReceiveTimeout = 3000; /* 3 seconds wait before timeout */
bytes = s.Receive(bytesReceived, bytesReceived.Length, 0); /* IMEOUT occurs!!! */
string page = Encoding.ASCII.GetString(bytesReceived, 0, bytes);
s.Close();
// Check to see if it was successful
if (page.Contains("MSA|AA"))
{
return true;
}
else
{
return false;
}
}
catch (SocketException e)
{
MessageBox.Show("SocketExecptionError:" + e);
return false;
}
}
private static Socket ConnectSocket(IPAddress server, int port)
{
Socket s = null;
IPHostEntry hostEntry = null;
// Get host related information.
hostEntry = Dns.GetHostEntry(server);
foreach (IPAddress address in hostEntry.AddressList)
{
IPEndPoint ipe = new IPEndPoint(address, port);
Socket tempSocket = new Socket(ipe.AddressFamily,SocketType.Stream,ProtocolType.Tcp);
tempSocket.Connect(ipe);
if (tempSocket.Connected)
{
s = tempSocket;
break;
}
else
{
continue;
}
}
return s;
}
I've been told that socket 5910 cannot receive ANY communications in Windows 7 due to Virus issues. Is this true? If so, I tried to connect to ANOTHER server on our network (PACS/RIS) socket # 5556. I get the SAME timeout error message.
The behaviour looks like the server doesn't understand your request / doesn't recognize it as a complete message according to the expected protocol.
As I understand from your code you are sending a HL7 message. I don't know this protocol, according to google it could be Health Level 7. The example I found is starting with some text, then a | as a delimiter. Your message is starting with |. Maybe there is the problem...
So you should have a look if the message you send is matching the protocol definition.

TCP/UDP Socket server on WAN

I have written a socket server in c# that will be used as the basic design for a small game project I am part of. The socket server works fine on lan. I able to communicate completely fine between the server and the client. However on the WAN the server receives all the correct messages from the client, but the client receives no messages from the server. Both the client and the server are behind a router but only the server's router has the ports forwarded. When the client connects to the server I get the IP address of the connection. Because the client is behind a NAT, is there more information from the sender that I need to collect? I assume the client could set up port forwarding but that would be VERY counter-productive to the game. Any help I can get is appreciated. If you need code let me know. Thanks in advance.
Used to make the TCP connection from the client
public string ConnectionAttempt(string ServeIP, string PlayUsername)
{
username = PlayUsername;
try
{
connectionClient = new TcpClient(ServeIP,TCP_PORT_NUMBER);
connectionClient.GetStream().BeginRead(readbuffer, 0, READ_BUFFER_SIZE, new AsyncCallback(DoRead), null);
Login(username);
ipAddress = IPAddress.Parse(((IPEndPoint)connectionClient.Client.RemoteEndPoint).Address.ToString());
servIP = new IPEndPoint(ipAddress,65002);
listenUDP = new IPEndPoint(ipAddress, 0);
UDPListenerThread = new Thread(receiveUDP);
UDPListenerThread.IsBackground = true;
UDPListenerThread.Start();
return "Connection Succeeded";
}
catch(Exception ex) {
return (ex.Message.ToString() + "Connection Failed");
}
}
Listens for a UDP message on a thread.
private void receiveUDP()
{
System.Net.IPEndPoint test = new System.Net.IPEndPoint(System.Net.IPAddress.Any, 0);
System.Net.EndPoint serverIP = (System.Net.EndPoint)test;
server.Bind(serverIP);
EndPoint RemoteServ = (EndPoint)servIP;
while (true)
{
byte[] content = new byte[1024];
int data = server.ReceiveFrom(content, ref RemoteServ);
string message = Encoding.ASCII.GetString(content);
result = message;
ProcessCommands(message);
}
}
Server TCP connection Listener:
private void ConnectionListen()
{
try
{
listener = new TcpListener(System.Net.IPAddress.Any, PORT_NUM);
listener.Start();
do
{
UserConnection client = new UserConnection(listener.AcceptTcpClient());
client.LineRecieved += new LineRecieve(OnLineRecieved);
UpdateStatus("Someone is attempting a login");
} while (true);
}
catch
{
}
}
Server UDP Listener:
private void receiveUDP()
{
System.Net.IPEndPoint test = new System.Net.IPEndPoint(System.Net.IPAddress.Any, UDP_PORT);
System.Net.EndPoint serverIP = (System.Net.EndPoint)test;
trans.Bind(serverIP);
System.Net.IPEndPoint ipep = new System.Net.IPEndPoint(System.Net.IPAddress.Any, 0);
System.Net.EndPoint Remote = (System.Net.EndPoint)ipep;
while (true)
{
byte[] content = new byte[1024];
int recv = trans.ReceiveFrom(content,ref Remote);
string message = Encoding.ASCII.GetString(content);
string[] data = message.Split((char)124);
//UpdateStatus(data[0] + data[1]);
UserConnection sender = (UserConnection)clients[data[0]];
sender.RemoteAdd = Remote;
if (data.Length > 2)
{
OnLineRecieved(sender, data[1] + "|" + data[2]);
}
else
{
OnLineRecieved(sender, data[1]);
}
}
}
Setup Information for a user connection Server-side:
Socket trans = new Socket(AddressFamily.InterNetwork,
SocketType.Dgram, ProtocolType.Udp); //UDP connection for data transmission in game.
public PlayerLoc Location = new PlayerLoc();
public UserConnection(TcpClient client)//TCP connection established first in the Constructor
{
this.client = client;
ipAdd = IPAddress.Parse(((IPEndPoint)client.Client.RemoteEndPoint).Address.ToString());
ipep = new IPEndPoint(ipAdd, ((IPEndPoint)client.Client.RemoteEndPoint).Port);
this.client.GetStream().BeginRead(readBuffer, 0, READ_BUFFER_SIZE, new AsyncCallback(StreamReciever), null);
}
Method for sending data to individual users:
public void SendData(string data)//UDP only used during transmission
{
byte[] dataArr = Encoding.ASCII.GetBytes(data);
trans.SendTo(dataArr, dataArr.Length,SocketFlags.None, RemoteAdd);
}
The client must start the UDP communication so that it can get a "hole" in the router/firewall. And the UDP server must reply back using the end point referenced in ReceviedFrom

Categories

Resources