Socket not receiving messages - c#

When I use "127.0.0.1" on the same computer, it works just fine. If I try to use the server's public ip address, it doesn't work (actually I get a socket error). If I make it ipaddress.any it doesn't give an error, but it doesn't work, either. I thought maybe it's because I'm on the same computer, so I put the server on my desktop and client on my laptop, and I connected my laptop to my phone's hotspot so the ipaddress is different. It still doesn't work. The message gets sent, but never received. What am I doing wrong?
struct DataPacket
{
public IPEndPoint destination;
public byte[] data;
public DataPacket(IPEndPoint destination, byte[] data)
{
this.destination = destination;
this.data = data;
}
}
AsyncPriorityQueue<DataPacket> queuedReceiveData = new AsyncPriorityQueue<DataPacket>(NetworkConstants.MAX_PLAYERS_PER_SERVER, false);
Socket sck;
IPEndPoint ipEndPoint;
bool listening = true;
bool processing = true;
void Start()
{
sck = new Socket(AddressFamily.InterNetwork, SocketType.Dgram, ProtocolType.Udp);
#if SERVER
ipEndPoint = new IPEndPoint(IPAddress.Any, NetworkConstants.SERVER_PORT);
sck.Bind(ipEndPoint);
#else
ipEndPoint = new IPEndPoint(IPAddress.Parse(NetworkConstants.SERVER_IP), NetworkConstants.SERVER_PORT);
EndPoint ep = new IPEndPoint(IPAddress.Any, 0); // doesn't work at all
//EndPoint ep = new IPEndPoint(IPAddress.Parse(NetworkConstants.SERVER_IP), 0); // says requested address is not valid in its context
//EndPoint ep = new IPEndPoint(IPAddress.Parse("127.0.0.1"), 0); // works only on same computer
sck.Bind(ep);
#endif
new Thread(() => ListenForData()).Start();
new Thread(() => ProcessData()).Start();
#if !SERVER
SerializeCompact.BitStream bs = new SerializeCompact.BitStream();
bs.Write(Headers.Connect, minHeader, maxHeader);
SendData(bs.GetByteArray());
#endif
}
void OnDestroy()
{
listening = false;
processing = false;
sck.Close();
}
public void SendData(byte[] data)
{
var packet = queuedSendData.Dequeue();
sck.SendTo(data, 0, data.Length, SocketFlags.None, ipEndPoint);
print("message sent to server");
}
public void SendDataTo(byte[] data, IPEndPoint endPoint)
{
var packet = queuedSendData.Dequeue();
sck.SendTo(data, 0, data.Length, SocketFlags.None, endPoint);
print("message sent to client");
}
void ListenForData()
{
while (listening)
{
EndPoint endPoint = ipEndPoint;
byte[] buffer = new byte[1024];
int rec = sck.ReceiveFrom(buffer, 0, buffer.Length, SocketFlags.None, ref endPoint);
Array.Resize(ref buffer, rec);
queuedReceiveData.Enqueue(new DataPacket((IPEndPoint) endPoint, buffer), 0);
print("received message");
ProcessData(buffer);
}
}
void ProcessData()
{
while (processing)
{
var rcv = queuedReceiveData.Dequeue(); // blocks until an item can be dequeued
byte[] data = rcv.data;
IPEndPoint ep = rcv.destination;
// process data...
}
}

Related

Client And Server Socket Connection using C#

I created two projects one with client and other with server to exchange text between both of them;on same computer i run those exe.
MY Client Side Connection Code connection looked :
using (SocketClient sa = new SocketClient(host, port))
{
sa.Connect();
Console.WriteLine(sa.SendReceive("Message #" + i.ToString()));
}
sa.Disconnect();
while socketclient is my class which contain these methods and constructor:
internal SocketClient(String hostName, Int32 port)
{
IPHostEntry host = Dns.GetHostEntry(hostName);
IPAddress[] addressList = host.AddressList;
this.hostEndPoint = new IPEndPoint(addressList[addressList.Length - 1], port);
this.clientSocket = new Socket(this.hostEndPoint.AddressFamily, SocketType.Stream, ProtocolType.Tcp);
}
internal void Connect()
{
SocketAsyncEventArgs connectArgs = new SocketAsyncEventArgs();
connectArgs.UserToken = this.clientSocket;
connectArgs.RemoteEndPoint = this.hostEndPoint;
connectArgs.Completed += new EventHandler<SocketAsyncEventArgs>(OnConnect);
clientSocket.ConnectAsync(connectArgs);
autoConnectEvent.WaitOne();
SocketError errorCode = connectArgs.SocketError;
if (errorCode != SocketError.Success)
{
throw new SocketException((Int32)errorCode);
}
}
internal void Disconnect()
{
clientSocket.Disconnect(false);
}
private void OnConnect(object sender, SocketAsyncEventArgs e)
{
autoConnectEvent.Set();
this.connected = (e.SocketError == SocketError.Success);
}
internal String SendReceive(String message)
{
if (this.connected)
{
Byte[] sendBuffer = Encoding.ASCII.GetBytes(message);
SocketAsyncEventArgs completeArgs = new SocketAsyncEventArgs();
completeArgs.SetBuffer(sendBuffer, 0, sendBuffer.Length);
completeArgs.UserToken = this.clientSocket;
completeArgs.RemoteEndPoint = this.hostEndPoint;
completeArgs.Completed += new EventHandler<SocketAsyncEventArgs>(OnSend);
clientSocket.SendAsync(completeArgs);
AutoResetEvent.WaitAll(autoSendReceiveEvents);
return Encoding.ASCII.GetString(completeArgs.Buffer, completeArgs.Offset,completeArgs.BytesTransferred);
}
else
{
throw new SocketException((Int32)SocketError.NotConnected);
}
}
while on server side code looks like that:
SocketListener sl = new SocketListener(numConnections, bufferSize);
sl.Start(port);
Console.WriteLine("Server listening on port {0}.
Press any key to terminate the server process...", port);
Console.Read();
sl.Stop();
Socket listener is my class which contain this method and constructor :
internal SocketListener(Int32 numConnections, Int32 bufferSize)
{
this.numConnectedSockets = 0;
this.numConnections = numConnections;
this.bufferSize = bufferSize;
this.readWritePool = new SocketAsyncEventArgsPool(numConnections);
this.semaphoreAcceptedClients = new Semaphore(numConnections, numConnections);
for (Int32 i = 0; i < this.numConnections; i++)
{
SocketAsyncEventArgs readWriteEventArg = new SocketAsyncEventArgs();
readWriteEventArg.Completed += new EventHandler<SocketAsyncEventArgs> (OnIOCompleted);
readWriteEventArg.SetBuffer(new Byte[this.bufferSize], 0, this.bufferSize);
this.readWritePool.Push(readWriteEventArg);
}
}
internal void Start(Int32 port)
{
IPAddress[] addressList = Dns.GetHostEntry(Environment.MachineName).AddressList;
IPEndPoint localEndPoint = new IPEndPoint(addressList[addressList.Length - 1], port);
this.listenSocket = new Socket(localEndPoint.AddressFamily, SocketType.Stream, ProtocolType.Tcp);
this.listenSocket.ReceiveBufferSize = this.bufferSize;
this.listenSocket.SendBufferSize = this.bufferSize;
if (localEndPoint.AddressFamily == AddressFamily.InterNetworkV6)
{
this.listenSocket.SetSocketOption(SocketOptionLevel.IPv6, (SocketOptionName)27, false);
this.listenSocket.Bind(new IPEndPoint(IPAddress.IPv6Any, localEndPoint.Port));
}
else
{
this.listenSocket.Bind(localEndPoint);
}
this.listenSocket.Listen(this.numConnections);
this.StartAccept(null);
mutex.WaitOne();
}
I have already port forward of my router because of server side exe which didn't listen without port forwarding.
it is working fine with send and receive on same pc and same port at home.
While when i try to run both of codes exe on my office computer it throws exception at following line:
Exception thrown by socket
Could any one guide me whats the problem and how to resolve it ?
Thanks
Have you tried temporary disable your Windows firewall ?

TCP Server with bi-directional communication

I have attempted to create a TCP service that is able to achieve what I wish but sadly I am getting stuck at the last hurdle.
The Scenario:
A single server instance is running with 10 clients all connected, a client will send a command, and receive the response. This is all working fine. However the last scenario isn't working
When a client issues an "UPDATE" command, the server should then send a message back to all connected clients that they need to do something.
Example Comms:
1
Client A GetTime -----> Server
Client A <----- Time is... Server
2
Client A UPDATE ------> Server
Client A <------- Ack Server
Client A <------- DoUpdate Server
Client B <------- DoUpdate Server
Client C <------- DoUpdate Server
Comms 1 abover works, mainly because of the call to send and call to reeive, but for comms 2 I cannot workout how I can achieve this, at least not without opening a second port for the communication which isn't ideal.
Current attempt based on Microsoft Article
Server
class Program
{
public static int Main(String[] args)
{
AsynchronousSocketListener.StartListening();
return 0;
}
}
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 static void StartListening()
{
// Data buffer for incoming data.
//var bytes = new Byte[1024];
// Establish the local endpoint for the socket.
// The DNS name of the computer
// running the listener is "host.contoso.com".
//??IPHostEntry ipHostInfo = Dns.Resolve(Dns.GetHostName());
//??IPAddress ipAddress = ipHostInfo.AddressList[0];
//??IPEndPoint localEndPoint = new IPEndPoint(ipAddress, 3030);
// Create a TCP/IP socket.
var listener = new Socket(AddressFamily.InterNetwork, SocketType.Stream, ProtocolType.Tcp);
// Bind the socket to the local endpoint and listen for incoming connections.
try
{
listener.Bind(new IPEndPoint(IPAddress.Any, 3030));
//listener.Bind(localEndPoint);
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((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.
var listener = (Socket)ar.AsyncState;
Socket handler = listener.EndAccept(ar);
// Create the state object.
var state = new StateObject {WorkSocket = handler};
handler.BeginReceive(state.Buffer, 0, StateObject.BufferSize, 0, ReadCallback, state);
}
public static void ReadCallback(IAsyncResult ar)
{
// Retrieve the state object and the handler socket
// from the asynchronous state object.
var 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.
var content = state.Sb.ToString();
if (content.IndexOf("<EOF>", StringComparison.Ordinal) > -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, ReadCallback, state);
}
}
}
private static void Send(Socket handler, String data)
{
// Convert the string data to byte data using ASCII encoding.
var byteData = Encoding.ASCII.GetBytes(data);
// Begin sending the data to the remote device.
handler.BeginSend(byteData, 0, byteData.Length, 0, SendCallback, handler);
}
private static void SendCallback(IAsyncResult ar)
{
try
{
// Retrieve the socket from the state object.
var 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());
}
}
/*
public static int Main(String[] args)
{
StartListening();
return 0;
}
* */
}
Client Code
class Program
{
public static int Main(String[] args)
//static void Main(string[] args)
{
Console.Title = "Client ";
AsynchronousClient.StartClient();
Console.ReadLine();
return 0;
}
}
public class StateObject
{
// Client socket.
public Socket WorkSocket = null;
// Size of receive buffer.
public const int BufferSize = 256;
// Receive buffer.
public byte[] Buffer = new byte[BufferSize];
// Received data string.
public StringBuilder Sb = new StringBuilder();
}
public class AsynchronousClient
{
// The port number for the remote device.
private const int Port = 3030;
// ManualResetEvent instances signal completion.
private static readonly ManualResetEvent ConnectDone =
new ManualResetEvent(false);
private static readonly ManualResetEvent SendDone =
new ManualResetEvent(false);
private static readonly ManualResetEvent ReceiveDone =
new ManualResetEvent(false);
// The response from the remote device.
private static String _response = String.Empty;
public 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.Resolve("host.contoso.com");
//??IPHostEntry ipHostInfo = Dns.Resolve("localhost");
//??IPAddress ipAddress = ipHostInfo.AddressList[0];
//??IPEndPoint remoteEP = new IPEndPoint(ipAddress, port);
// Create a TCP/IP socket.
var client = new Socket(AddressFamily.InterNetwork, SocketType.Stream, ProtocolType.Tcp);
// Connect to the remote endpoint.
//client.BeginConnect(remoteEP,
//new AsyncCallback(ConnectCallback), client);
var remoteEP = new IPEndPoint(IPAddress.Parse("127.0.0.1"), Port);
client.BeginConnect(remoteEP, ConnectCallback, client);
ConnectDone.WaitOne();
// set receive to another thread so we can constantly receive, doesn't work as intended
//var thread = new Thread(() => ReadThread(client));
//thread.Start();
// Send test data to the remote device.
Send(client, "This is a test<EOF>");
SendDone.WaitOne();
//test remove
// 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());
}
}
// doesn't work as expected
private static void ReadThread(object ar)
{
var client = (Socket)ar;
while (true)
{
Receive(client);
ReceiveDone.WaitOne();
// Write the response to the console.
Console.WriteLine("Response received : {0}", _response);
}
}
private static void ConnectCallback(IAsyncResult ar)
{
try
{
// Retrieve the socket from the state object.
var client = (Socket)ar.AsyncState;
// Complete the connection.
client.EndConnect(ar);
Console.WriteLine("Socket connected to {0}", client.RemoteEndPoint);
// Signal that the connection has been made.
ConnectDone.Set();
}
catch (Exception e)
{
Console.WriteLine(e.ToString());
}
}
private static void Receive(Socket client)
{
try
{
// Create the state object.
var state = new StateObject {WorkSocket = client};
// Begin receiving the data from the remote device.
client.BeginReceive(state.Buffer, 0, StateObject.BufferSize, 0, ReceiveCallback, state);
}
catch (Exception e)
{
Console.WriteLine(e.ToString());
}
}
private static void ReceiveCallback(IAsyncResult ar)
{
try
{
// Retrieve the state object and the client socket
// from the asynchronous state object.
var state = (StateObject)ar.AsyncState;
Socket client = state.WorkSocket;
// Read data from the remote device.
int bytesRead = client.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));
// Get the rest of the data.
client.BeginReceive(state.Buffer, 0, StateObject.BufferSize, 0, ReceiveCallback, state);
}
else
{
// All the data has arrived; put it in response.
if (state.Sb.Length > 1)
{
_response = state.Sb.ToString();
}
// Signal that all bytes have been received.
ReceiveDone.Set();
}
}
catch (Exception e)
{
Console.WriteLine(e.ToString());
}
}
private static void Send(Socket client, String data)
{
// Convert the string data to byte data using ASCII encoding.
var byteData = Encoding.ASCII.GetBytes(data);
// Begin sending the data to the remote device.
client.BeginSend(byteData, 0, byteData.Length, 0, SendCallback, client);
}
private static void SendCallback(IAsyncResult ar)
{
try
{
// Retrieve the socket from the state object.
var 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());
}
}
/*
public static int Main(String[] args)
{
StartClient();
return 0;
}
*/
}
Previous system that worked
Server:
class Program
{
private static byte[] buffer = new byte[1024];
public static Socket _serverSocket = new Socket(AddressFamily.InterNetwork, SocketType.Stream, ProtocolType.Tcp);
public static List<Socket> clientSockets = new List<Socket>();
static void Main(string[] args)
{
Console.Title = "Server, " + clientSockets.Count + " clients are connected";
SetupServer();
Console.ReadLine();
}
public static void SetupServer()
{
Console.WriteLine("Setting up server...");
_serverSocket.Bind(new IPEndPoint(IPAddress.Any, 3030));
_serverSocket.Listen(10);
_serverSocket.BeginAccept(AcceptCallback, null);
Console.ReadLine();// stops cmd from closing
}
public static void AcceptCallback(IAsyncResult AR)
{
Socket socket = _serverSocket.EndAccept(AR);
if (!clientSockets.Contains(socket))
clientSockets.Add(socket);
IPEndPoint remoteIPEndPoint = socket.RemoteEndPoint as IPEndPoint;
Console.WriteLine(remoteIPEndPoint.Address);
Console.WriteLine("Client Connected");
Console.Title = "Server, " + clientSockets.Count + " clients are connected";
socket.BeginReceive(buffer, 0, buffer.Length, SocketFlags.None, RecieveCallBack, socket);
_serverSocket.BeginAccept(AcceptCallback, null);
}
private static void RecieveCallBack(IAsyncResult AR)
{
var socket = (Socket)AR.AsyncState;
int received = socket.EndReceive(AR);
var databuff = new byte[received];
Array.Copy(buffer, databuff, received);
string s = Encoding.ASCII.GetString(databuff);
Console.WriteLine("Text Received: " + s);
string response = string.Empty;
switch (s.ToLower())
{
case "get time":
response = DateTime.Now.ToLongTimeString();
break;
case "hello":
response = "olleh";
break;
case "update clients":
response = "";
SendData("Ack", socket);
doUpdateClients();
break;
default:
response = "Invavlid Request";
break;
}
SendData(response, socket);
}
private static void SendData(string Data, Socket socket)
{
byte[] data = Encoding.ASCII.GetBytes(Data);
socket.BeginSend(data, 0, data.Length, SocketFlags.None, sendCallback, socket);
socket.BeginReceive(buffer, 0, buffer.Length, SocketFlags.None, RecieveCallBack, socket);
}
private static void doUpdateClients()
{
// need to send an update message to all the clients
var upd = new Thread((UpdateClients));
upd.Start();
}
private static void UpdateClients()
{
Thread.Sleep(5000);
foreach (var sock in clientSockets)
{
SendData("UpdateClients", sock);
}
}
private static void sendCallback(IAsyncResult AR)
{
var socket = (Socket)AR.AsyncState;
socket.EndSend(AR);
}
//
}
}
Client:
class Program
{
private static byte[] buffer = new byte[1024];
public static Socket _clientSocket = new Socket(AddressFamily.InterNetwork, SocketType.Stream, ProtocolType.Tcp);
static void Main(string[] args)
{
Console.Title = "Client ";
LoopConnect();
//ReceiveLoopStart();
//_clientSocket.Listen(10);
SendLoop();
Console.ReadLine();
}
private static void LoopConnect()
{
while (!_clientSocket.Connected)
{
try
{
_clientSocket.Connect(IPAddress.Parse("127.0.0.1"), 3030);
}
catch (SocketException se)
{
}
}
Console.WriteLine("Connected");
}
private static void ReceiveLoopStart()
{
//_clientSocket.Bind(new IPEndPoint(IPAddress.Any, 3030));
//_clientSocket.Listen(10);
_clientSocket.BeginAccept(AcceptCallback, null);
Thread receiveThread = new Thread(ReceiveLoop);
receiveThread.Start();
}
private static void ReceiveLoop()
{
_clientSocket.BeginReceive(buffer, 0, buffer.Length, SocketFlags.None, RecieveCallBack, _clientSocket);
_clientSocket.BeginAccept(AcceptCallback, null);
}
private static void RecieveCallBack(IAsyncResult AR)
{
int received = _clientSocket.EndReceive(AR);
var databuff = new byte[received];
Array.Copy(buffer, databuff, received);
string s = Encoding.ASCII.GetString(databuff);
Console.WriteLine("Text Received: " + s);
string response = string.Empty;
switch (s.ToLower())
{
case "get time":
response = DateTime.Now.ToLongTimeString();
break;
case "hello":
response = "olleh";
break;
default:
response = "Invavlid Request";
break;
}
}
public static void AcceptCallback(IAsyncResult AR)
{
Socket socket = _clientSocket.EndAccept(AR);
Console.WriteLine("Client Connected");
socket.BeginReceive(buffer, 0, buffer.Length, SocketFlags.None, RecieveCallBack, socket);
_clientSocket.BeginAccept(AcceptCallback, null);
}
private static void SendLoop()
{
while (true)
{
Console.Write("Enter Request: ");
string req = Console.ReadLine();
var buffer = Encoding.ASCII.GetBytes(req);
_clientSocket.Send(buffer);
var tempBuff = new byte[1024];
int rec = _clientSocket.Receive(tempBuff);
var data = new byte[rec];
Array.Copy(tempBuff, data, rec);
Console.WriteLine("Received: " + Encoding.ASCII.GetString(data));
}
}
}
}
I don't have an example up my sleeve here in C# but what you need to learn is to use the select api.
You only need a single thread to do this. You use the same thread to process all sockets that are in use at any point in time.
If nobody is connected you only have the listening socket. And you then only use the select api to watch what happens on that socket. Select is a blocking call when no timeout is specified. If data is available, then that means that you can call accept. The result of accept is as you know another socket. You now use 2 sockets in select. Again select will block until one of those sockets has data. Perhaps the listening socket again, so you get another socket after calling accept. You now use 3 sockets in select. Suppose now one of the accept sockets have data available you will see that by the using the select api properly. And you can then use any of those sockets to send something over it, except of course the listening socket that is not intended for sending.
More info can be found here :
http://www.codeproject.com/Articles/20066/A-scalable-client-server-using-select-socket-funct
It uses what I explained and gives more elaborate explanations too.
I'm not getting in to your design , but it seems like you can't even reference the other clients.
why don't you save a collection of sockets like so :
private List<Socket> _handlers = new List<Socket>();
public static void AcceptCallback(IAsyncResult ar)
{
Socket handler = listener.EndAccept(ar);
var state = new StateObject {WorkSocket = handler};
handlers.Add(handler);
handler.BeginReceive(state.Buffer, 0, StateObject.BufferSize, 0, ReadCallback, state);
}
And then on receive according to the message type or whatever you should notify these clients.( all of them not just the one currently passed to the ReciveCallback.
public static void ReadCallback(IAsyncResult ar)
{
if("<EOF>")
{
foreach(var h in _handlers)
{
Send(h,data);
}
}
}

Cannot connect to server with external ip via socket.connect() in c#

I'm connecting to my server on the internal network. But I cannot connect to a server on an external network. The server's firewall on the external network closed. The port forwarding server was.
Server side codes:
private byte[] _buffer = new byte[1024];
private List<Socket> _clientSockets = new List<Socket>();
private Socket _serverSocket = new Socket(AddressFamily.InterNetwork, SocketType.Stream, ProtocolType.Tcp);
public int PortNo;
private void SetupServer()
{
try
{
_serverSocket.Bind(new IPEndPoint(IPAddress.Any, PortNo));
_serverSocket.Listen(1);
_serverSocket.BeginAccept(new AsyncCallback(AcceptCallBack), null);
}
catch(Exception hata)
{
MessageBox.Show(hata.Message);
}
}
private void AcceptCallBack(IAsyncResult AR)
{
Socket socket = _serverSocket.EndAccept(AR);
_clientSockets.Add(socket);
try
{
socket.BeginReceive(_buffer, 0, _buffer.Length, SocketFlags.None, new AsyncCallback(ReceiveCallBack), socket);
_serverSocket.BeginAccept(new AsyncCallback(AcceptCallBack), null);
}
catch(Exception hata)
{
MessageBox.Show(hata.Message);
}
}
private void ReceiveCallBack(IAsyncResult AR)
{
Socket socket = (Socket)AR.AsyncState;
int received = socket.EndReceive(AR);
byte[] dataBuf = new byte[received];
Array.Copy(_buffer, dataBuf, received);
string text = Encoding.ASCII.GetString(dataBuf);
byte[] response = response = ekranGonderme();
try
{
socket.BeginSend(response, 0, response.Length, SocketFlags.None, new AsyncCallback(SendCallBack), null);
socket.BeginReceive(_buffer, 0, _buffer.Length, SocketFlags.None, new AsyncCallback(ReceiveCallBack), socket);
}
catch(Exception hata)
{
MessageBox.Show(hata.Message);
}
}
Client Side Codes:
private static Socket _clientSocket = new Socket(AddressFamily.InterNetwork, SocketType.Stream, ProtocolType.Tcp);
int portNo = 20000;
IPAddress[] server_ip = Dns.GetHostAddresses(server's external ip address);
private void Form1_Load(object sender, EventArgs e)
{
LoopConnect();
LoopSendReceive()
}
private void LoopSendReceive()
{
try
{
byte[] buffer = Encoding.ASCII.GetBytes("ekran_iste");
_clientSocket.Send(buffer);
byte[] receiveBuf = new byte[999999];
int rec = _clientSocket.Receive(receiveBuf);
byte[] data = new byte[rec];
Array.Copy(receiveBuf, data, rec);
MemoryStream ms = new MemoryStream(data);
}
catch
{
}
}
private void LoopConnect()
{
int attempts = 0;
while (!_clientSocket.Connected)
{
try
{
attempts++;
_clientSocket.Connect(server_ip[0], portNo);
}
catch(SocketException)
{
}
}
}
}

Send video frame via socket

I captured video stream with Kinect device. I need to Send this streams over network. For this purpose I used sockets.
Her is piece of code in server and client:
private System.Drawing.Bitmap _CurrentBitmap;
public ManWindow()
{
InitializeComponent();
this.Loaded += delegate
{
BackgroundWorker bw1 = new BackgroundWorker();
bw1.RunWorkerCompleted += (a, b) => bw1.RunWorkerAsync();
bw1.DoWork += delegate { SendImage(); };
bw1.RunWorkerAsync();
};
}
public void SendImage()
{
Socket sListen = new Socket(AddressFamily.InterNetwork,
SocketType.Stream,
ProtocolType.Tcp);
IPAddress IP = IPAddress.Parse("127.0.0.1");
IPEndPoint IPE = new IPEndPoint(IP, 4321);
sListen.Bind(IPE);
sListen.Listen(2);
while (true)
{
Socket clientSocket;
clientSocket = sListen.Accept();
var converter = new System.Drawing.ImageConverter();
byte[] buffer = (byte[])converter.ConvertTo(_CurrentBitmap, typeof(byte[]));
clientSocket.Send(buffer, buffer.Length, SocketFlags.None);
}
}
Client:
private void Window_Loaded(object sender, RoutedEventArgs e)
{
BackgroundWorker bw11111 = new BackgroundWorker();
bw11111.RunWorkerCompleted += (a, b) => bw11111.RunWorkerAsync();
bw11111.DoWork += delegate { Recive(); };
bw11111.RunWorkerAsync();
Recive();
}
public void Recive()
{
Socket s = new Socket(AddressFamily.InterNetwork,
SocketType.Stream,
ProtocolType.Tcp);
IPAddress IP = IPAddress.Parse("127.0.0.1");
IPEndPoint IPE = new IPEndPoint(IP, 4321);
s.Connect(IPE);
while (true)
{
byte[] buffer = new byte[1000000];
s.Receive(buffer, buffer.Length, SocketFlags.None);
MemoryStream ms = new MemoryStream(buffer);
ms.Write(buffer, 0, buffer.Length);
System.Drawing.Bitmap bitmap = new System.Drawing.Bitmap(ms);
Dispatcher.BeginInvoke(new Action(() =>
{
rgbImage11.Source = bitmap.ToBitmapSource();
}));
}
}
_CurrentBitmap is frame that readed from Kinect and every 1 second updated. When Client starts, call Socket Receive method, it receives frame and after convert to bitmap asign it to Image WPF control. My problem is this action occurs ones and loop in client not repeated.
I think you are doing it right, although depending on your needs UDP sockets might make more sense.
Try changing your Server code to something like this:
while (true)
{
Socket clientSocket;
clientSocket = sListen.Accept();
var converter = new System.Drawing.ImageConverter();
while(true) // find a better way to determine that the picture is still updating?
{
byte[] buffer = (byte[])converter.ConvertTo(_CurrentBitmap, typeof(byte[]));
clientSocket.Send(buffer, buffer.Length, SocketFlags.None);
}
}
You were sending one bitmap to your client, then falling out of the loop.
The socket will not stay open, so your client runs it's loop once.

C# UDP Server/Client - NAT

Iam trying to send a message (via UDP) from my client to my server. The server should answer this message and if the client receives this answer he should print out a message.
If i run the client and server on my local network everything works fine.
If i try to connect through the internet from another PC outside my network the server receives the request of the client, sends an answer back, but the client never receives this answer. The client and the server are both behind a NAT but i portforwarded the ports at the server´s NAT and the server got its own DNS. I already tried NAT traversal but it gives me the same IP and port adress as the IPEndPoint of the server, after receiveing the request of the client, does.
I´ve got no idea how to fix this, so any guidance would be much appreciated.
Client
public static void Main()
{
Thread receiveThread = new Thread(new ThreadStart(ReceiveData));
receiveThread.Start();
object[] oData = {1};
sendData(oData, 0,0, "Li");
while (true)
{
Console.ReadLine();
}
}
private void receiveData()
{
string receivePort = 8080;
Socket client = new Socket(AddressFamily.InterNetwork, SocketType.Dgram, ProtocolType.Udp);
client.ReceiveTimeout = 1000;
IPEndPoint end = new IPEndPoint(IPAddress.Any, receivePort);
client.Bind(end);
while (true)
{
try
{
byte[] data = new byte[1024];
client.Receive(data, 0, data.Length, SocketFlags.None);
object[] receivedObj = Deserialize(data);
string sType = (string)receivedObj[3];
if (sType == "Li")
{
console.WriteLine("received Li");
}
}
catch (Exception err)
{
Console.WriteLine(err.ToString());
}
}
}
public static void sendData(object[] oData, int iFrom, int iTo, string sType)
{
string sendPort = 17171;
UdpClient client = new UdpClient();
string IP = "ThisIsTheDNSofmyServer.com"; //ServerDNS
//string IP = "192.168.xxx.xxx"; //serverIP in LAN
if (IP.StartsWith("T"))
{
IP = (Dns.GetHostAddresses(IP))[0].ToString();
}
IPEndPoint remoteEndPoint = new IPEndPoint(IPAddress.Parse(IP), sendPort);
oData[1] = iFrom;
oData[2] = iTo;
oData[3] = sType;
Byte[] data = Serialize(oData);
client.Send(data, data.Length, remoteEndPoint);
}
The server´s code is almost the same:
public static void Main()
{
Thread receiveThread = new Thread(new ThreadStart(ReceiveData));
receiveThread.Start();
while (true)
{
Console.ReadLine();
}
}
private static void ReceiveData()
{
int receivePort = 17171;
UdpClient client = new UdpClient(receivePort);
while (true)
{
try
{
IPEndPoint anyIP = new IPEndPoint(IPAddress.Any, 0);
byte[] data = new byte[1024];
data = client.Receive(ref anyIP);
object[] receivedObj = Deserialize(data);
//if I receive data send an Answer
sendData(receivedObj, 0,0,"Li",anyIP.Address.ToString());
}
catch (Exception err)
{
Console.WriteLine(err.ToString());
}
}
}
private static void sendData(object[] oData, int iFrom, int iTo, string sType, string IP)
{
int sendPort = 8080;
object[] paket = { oData, iFrom, iTo, sType };
UdpClient client = new UdpClient();
IPEndPoint remoteEndPoint = new IPEndPoint(IPAddress.Parse(IP), sendPort);
client.Send(data, data.Length, remoteEndPoint);
}
i believe this is a port cofniguration issue,
8080 is almost likely to be configured as alternate http
"The UdpClient you use to receive datagrams must be created using the multicast port number" from MSDN
Hope this helps and good luck
Krishna
You do not need to do anything unordinary to traverse NAT in the setup you described, you just need to send it from the server back to your client; specifically: you must send back to the end point, i.e. IP and port, you received it on.
client.Send(data, data.Length, remoteEndPoint); // remoteEndPoint is the IPEndPoint you got the datagram on

Categories