I'm trying to figure out how I can send & receive data via the UDP protocol using C# as a client, and having a JS server running that will transmit a "response" packet for testing purposes.
Below is the UDP class that I made for testing, it's simply just 2 threads:
One that read the received data from UDP and another thread for sending data.
using System;
using System.Collections.Generic;
using System.Text;
using System.Net;
using System.Net.Sockets;
using System.Threading;
namespace UDPTesting {
class UDPHandler {
private int receivePort, sendPort;
private string serverIP;
private IPEndPoint sendEndPoint, receiveEndPoint;
public UDPHandler(string serverIP, int receivePort, int sendPort) {
this.serverIP = serverIP;
this.receivePort = receivePort;
this.sendPort = sendPort;
this.sendEndPoint = new IPEndPoint(IPAddress.Parse(this.serverIP), this.sendPort);
this.receiveEndPoint = new IPEndPoint(IPAddress.Parse(this.serverIP), this.receivePort);
this.readerUdpClient();
this.senderUdpClient();
}
void readerUdpClient() {
UdpClient readerClient = new UdpClient();
IPEndPoint localEndpoint = new IPEndPoint(IPAddress.Any, 3000);
readerClient.Client.Bind(localEndpoint); //Tried both Connect and Bind
//readerClient.Connect(this.receiveEndPoint);
Thread t = new Thread(() => {
Console.WriteLine("Awaiting data from server...");
var remoteEP = new IPEndPoint(IPAddress.Any, 3000);
byte[] bytesReceived = readerClient.Receive(ref remoteEP);
//The above throws: System.InvalidOperationException: 'You must call the Bind method before performing this operation'
Console.WriteLine("Received data from " + remoteEP.ToString());
});
t.Start();
}
void senderUdpClient() {
UdpClient senderClient = new UdpClient();
senderClient.Connect(this.sendEndPoint);
string sendString = "1;2;3";
byte[] bytes = toBytes(sendString);
Thread t = new Thread(() => {
while (true) {
senderClient.Send(bytes, bytes.Length);
Thread.Sleep(1000);
}
});
t.Start();
}
public byte[] toBytes(string text) {
return Encoding.UTF8.GetBytes(text);
}
public string fromBytes(byte[] bytes) {
return Encoding.UTF8.GetString(bytes);
}
}
}
Additionally my "main" for my program is this:
using System;
using System.Threading;
namespace UDPTesting {
class Program {
static void Main(string[] args) {
string serverIP = "46.101.102.243";
int sendPort = 41234;
int receivePort = 3000;
UDPHandler handler = new UDPHandler(serverIP, receivePort, sendPort);
}
}
}
How can I read the response that the server sends in the client, at the same time as I send data from the client to the server?
We tested it individually:
1) Sending a UDP packet from client -> server works, as I can see that the server receives the packet.
2) Sending a UDP packet from server -> client works, as I can see the client receives the packet.
3) When the client tries to send and read simultaneously, it will send data to the server, but will not read the response.
Any help would be greatly appreciated!
Your receiving function should work like this
void readerUdpClient()
{
new Thread(() => {
UdpClient readerClient = new UdpClient(receivePort);
Console.WriteLine("Awaiting data from server...");
var remoteEP = new IPEndPoint(IPAddress.Any, 0);
byte[] bytesReceived = readerClient.Receive(ref remoteEP);
Console.WriteLine($"Received {bytesReceived.Length} bytes from {remoteEP}");
}).Start();
}
The UdpClient constructor that takes a port automatically binds the local end point for you.
Related
I am UsingClient.Send(Encoding.ASCII.GetBytes(Message)); to send a message to the client, when i tried sending a second message it doesn't give any error so i think it send with no problem but it never reaches the client (127.0.0.1)
Code That Send
public void SendMessage(Socket _Client, string Message)
{
foreach (Socket Client in Clients)
{
IPEndPoint TargetEndPoint = _Client.LocalEndPoint as IPEndPoint;
IPAddress TargetIp = TargetEndPoint.Address;
int TargetPort = TargetEndPoint.Port;
IPEndPoint ClientEndPoint = Client.LocalEndPoint as IPEndPoint;
IPAddress ClientIp = ClientEndPoint.Address;
int ClientPort = ClientEndPoint.Port;
if (TargetIp.ToString() == ClientIp.ToString() && TargetPort == ClientPort)
{
Client.Send(Encoding.ASCII.GetBytes(Message));
//Client.EndSend();
}
}
}
Code That Receive
private void RecivedCallBack(IAsyncResult Result)
{
//Create a int with the Buffer Size
int BufferSize = _Socket.EndReceive(Result);
//Create a new byte array with the Buffer Size
byte[] Packet = new byte[BufferSize];
//Copy Buffer to Packet
Array.Copy(_Buffer, Packet, Packet.Length);
//Handle Packet
PacketHandler.Packet(Encoding.UTF8.GetString(Packet));
//Makes _Buffer a new byte
_Buffer = new byte[1024];
//Get Ready to recive data
_Socket.BeginReceive(_Buffer, 0, _Buffer.Length, SocketFlags.None, RecivedCallBack, null);
}
Code that Handle
public static void Packet(string Message)
{
Console.WriteLine(Message);
switch (Message)
{
case "StartChat":
_ChatForm Start = new _ChatForm();
Start.ShowDialog();
break;
case "StopChat":
_ChatForm._Chat.EndChat();
break;
}
}
TCP is stream based, so your client has no way to know when the message has ended. Either use UDP, implement a way to detect the end of messages (eg send a 4 byte message with the length of the real message, before sending the real message... and read on the client until the whole message has been received), or use a library. I like Hazel: https://github.com/DarkRiftNetworking/Hazel-Networking.
The great thing about Hazel is that it implements reliable UDP. So, if you need to have your "messages" arrive in the order in which they were sent, or if you need guaranteed delivery and receipt of such messages (such as what TCP provides), then you can do so with their reliable UDP implementation.
They will also implement Web Sockets at some point :) Good luck!
A client/server example from the documentation:
Server
using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
using System.Threading.Tasks;
using System.Net;
using Hazel;
using Hazel.Tcp;
namespace HazelExample
{
class ServerExample
{
static ConnectionListener listener;
public static void Main(string[] args)
{
listener = new TcpConnectionListener(IPAddress.Any, 4296);
listener.NewConnection += NewConnectionHandler;
Console.WriteLine("Starting server!");
listener.Start();
Console.WriteLine("Press any key to continue...");
Console.ReadKey();
listener.Close();
}
static void NewConnectionHandler(object sender, NewConnectionEventArgs args)
{
Console.WriteLine("New connection from " + args.Connection.EndPoint.ToString();
args.Connection.DataReceived += DataReceivedHandler;
args.Recycle();
}
private static void DataReceivedHandler(object sender, DataEventArgs args)
{
Connection connection = (Connection)sender;
Console.WriteLine("Received (" + string.Join<byte>(", ", args.Bytes) + ") from " + connection.EndPoint.ToString());
connection.SendBytes(args.Bytes, args.SendOption);
args.Recycle();
}
}
}
Client
using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
using System.Threading.Tasks;
using Hazel;
using Hazel.Tcp;
namespace HazelExample
{
class ClientExample
{
static Connection connection;
public static void Main(string[] args)
{
NetworkEndPoint endPoint = new NetworkEndPoint("127.0.0.1", 4296);
connection = new TcpConnection(endPoint);
connection.DataReceived += DataReceived;
Console.WriteLine("Connecting!");
connection.Connect();
Console.WriteLine("Press any key to continue...");
Console.ReadKey();
connection.Close();
}
}
}
Closed. This question needs debugging details. It is not currently accepting answers.
Edit the question to include desired behavior, a specific problem or error, and the shortest code necessary to reproduce the problem. This will help others answer the question.
Closed 6 years ago.
Improve this question
Hi I written simple client socket application, where client send some string to server, server receives it and convert the string to upper case and send back to client. Client print the message from server to console. But When I ran the application, I am getting 'input string was not in correct format' error while converting the bytes received from server. Since I am new to C# programming, Can some one help me to understand why this error coming, and how to resolve it?
Server.cs
using System;
using System.Text;
using System.Net;
using System.Net.Sockets;
namespace Server
{
public class ServerSocket
{
private int port;
private Socket serverSocket;
public ServerSocket(int port)
{
this.port = port;
serverSocket = new Socket(AddressFamily.InterNetwork, SocketType.Stream, ProtocolType.Tcp);
IPEndPoint serverEndPoint = new IPEndPoint(IPAddress.Parse("127.0.0.1"), port);
/* Associates a Socket with a local endpoint. */
serverSocket.Bind(serverEndPoint);
/*Places a Socket in a listening state.
* The maximum length of the pending connections queue is 100
*/
serverSocket.Listen(100);
}
public void start()
{
Console.WriteLine("Starting the Server");
/* Accept Connection Requests */
Socket accepted = serverSocket.Accept();
/* Get the size of the send buffer of the Socket. */
int bufferSize = accepted.SendBufferSize;
byte[] buffer = new byte[bufferSize];
/* Receives data from a bound Socket into a receive buffer. It return the number of bytes received. */
int bytesRead = accepted.Receive(buffer);
byte[] formatted = new byte[bytesRead];
for (int i = 0; i < bytesRead; i++)
{
formatted[i] = buffer[i];
}
String receivedData = Encoding.UTF8.GetString(formatted);
Console.WriteLine("Received Data " + receivedData);
String response = receivedData.ToUpper();
byte[] resp = Encoding.UTF8.GetBytes(response);
accepted.Send(resp, 0, resp.Length, 0);
Console.WriteLine("Press some key to close");
Console.Read();
}
}
class Server
{
static void Main(string[] args)
{
ServerSocket server = new ServerSocket(1234);
server.start();
}
}
}
Client.cs
using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
using System.Threading.Tasks;
using System.Net;
using System.Net.Sockets;
namespace client
{
public class ClientSocket{
private Socket clientSocket;
private int port;
public ClientSocket(int port)
{
this.port = port;
clientSocket = new Socket(AddressFamily.InterNetwork, SocketType.Stream, ProtocolType.Tcp);
}
public void start()
{
Console.WriteLine("Starting client socket");
try
{
IPEndPoint serverEndPoint = new IPEndPoint(IPAddress.Parse("127.0.0.1"), port);
clientSocket.Connect(serverEndPoint);
Console.WriteLine("Enter some data to send to server");
String data = Console.ReadLine();
byte[] bytes = Encoding.UTF8.GetBytes(data);
clientSocket.Send(bytes);
Console.WriteLine("Closing connection");
int receiveBufferSize = clientSocket.ReceiveBufferSize;
byte[] buffer = new byte[receiveBufferSize];
int receivedBytes = clientSocket.Receive(buffer);
byte[] receivedData = new byte[receivedBytes];
for(int i=0; i < receivedBytes; i++)
{
receivedData[i] = buffer[i];
Console.WriteLine(receivedData[i]);
}
String received = Encoding.UTF8.GetString(receivedData);
Console.WriteLine("Response : {}", received);
Console.WriteLine("Press Enter to close");
Console.Read();
clientSocket.Close();
}
catch (Exception e)
{
Console.WriteLine("Error while connectiong to server {}", e.Message );
}
}
}
class Client
{
static void Main(string[] args)
{
ClientSocket clientSocket = new ClientSocket(1234);
clientSocket.start();
}
}
}
The line:
Console.WriteLine("Response : {}", received);
should be:
Console.WriteLine("Response : {0}", received);
I have a question with my UDP client server app.
I have a connection between the two. They both send data to each other. Only the server receives data from the client but not the other way around but the server is sending. What am I doing wrong?
using System;
using System.Globalization;
using System.Net;
using System.Net.Sockets;
using System.Text;
namespace PewPewGame
{
class Client
{
UdpClient udpClient;
IPEndPoint RemoteIpEndPoint;
String serverIp;
String[] dataAray;
GameScreen gameScreen;
Player otherPlayer;
public Client(string serverIp, GameScreen gameScreen, Player otherPlayer)
{
this.gameScreen = gameScreen;
this.otherPlayer = otherPlayer;
udpClient = new UdpClient();
this.serverIp = serverIp;
}
public void clientThread()
{
udpClient = new UdpClient(serverIp,1002);
while (true)
{
RemoteIpEndPoint = new IPEndPoint(IPAddress.Parse(serverIp), 1002);
receiveData();
}
}
public void receiveData()
{
Byte[] receiveBytes = udpClient.Receive(ref RemoteIpEndPoint);
String clientData = Encoding.ASCII.GetString(receiveBytes);
dataAray = clientData.Split(',');
otherPlayer.x = Convert.ToInt32(dataAray[0]);
otherPlayer.y = Convert.ToInt32(dataAray[1]);
if (dataAray[3] == "1")
{
gameScreen.otherProjectile = new Projectile(Convert.ToInt16(dataAray[0]), Convert.ToInt16(dataAray[1]), 2, 4, 8, 8, dataAray[2]);
}
}
public void sendData(string data)
{
Byte[] senddata = Encoding.ASCII.GetBytes(data);
udpClient.Send(senddata, senddata.Length);
}
public static IPEndPoint CreateIPEndPoint(string endPoint)
{
string[] ep = endPoint.Split(':');
if (ep.Length < 2) throw new FormatException("Invalid endpoint format");
IPAddress ip;
if (ep.Length > 2)
{
if (!IPAddress.TryParse(string.Join(":", ep, 0, ep.Length - 1), out ip))
{
throw new FormatException("Invalid ip-adress");
}
}
else
{
if (!IPAddress.TryParse(ep[0], out ip))
{
throw new FormatException("Invalid ip-adress");
}
}
int port;
if (!int.TryParse(ep[ep.Length - 1], NumberStyles.None, NumberFormatInfo.CurrentInfo, out port))
{
throw new FormatException("Invalid port");
}
return new IPEndPoint(ip, port);
}
}
}
using System;
using System.Net;
using System.Net.Sockets;
using System.Text;
using System.Threading.Tasks;
namespace PewPewGame
{
class Server
{
UdpClient udpClient;
IPEndPoint RemoteIpEndPoint;
String[] dataAray;
GameScreen gameScreen;
Player otherPlayer;
public Server(GameScreen gameScreen, Player otherPlayer)
{
this.gameScreen = gameScreen;
this.otherPlayer = otherPlayer;
}
public void serverThread()
{
udpClient = new UdpClient(1002);
while (true)
{
RemoteIpEndPoint = new IPEndPoint(IPAddress.Any, 0);
receiveData();
}
}
public void sendData(string data)
{
Byte[] senddata = Encoding.ASCII.GetBytes(data);
udpClient.Send(senddata, senddata.Length);
}
public void receiveData()
{
Byte[] receiveBytes = udpClient.Receive(ref RemoteIpEndPoint);
try
{
String clientData = Encoding.ASCII.GetString(receiveBytes);
dataAray = clientData.Split(',');
otherPlayer.x = Convert.ToInt32(dataAray[0]);
otherPlayer.y = Convert.ToInt32(dataAray[1]);
if (dataAray[3] == "1")
{
gameScreen.otherProjectile = new Projectile(Convert.ToInt16(dataAray[0]), Convert.ToInt16(dataAray[1]), 2, 4, 8, 8, dataAray[2]);
}
}
catch { }
}
}
}
First of all: UDP knows no 'connection', so your first line is confusing.
Then you're using the UdpClient.Send(byte[], int) method to send data, but that expects a previous (confusingly named) call to Connect(string, int) or using the UdpClient constructor you're using for the client: new UdpClient(string, int).
I'm pretty sure your empty catch block (do not do this, and especially do not do this if something doesn't work as expected!) catches and swallows a SocketException per the remarks from [1]:
This overload sends datagrams to the remote host established in the Connect method and returns the number of bytes sent. If you do not call Connect before calling this overload, the Send method will throw a SocketException. If you receive a SocketException, use SocketException.ErrorCode to obtain the specific error code. Once you have obtained this code, you can refer to the Windows Sockets version 2 API error code documentation in MSDN for a detailed description of the error.
If you want to send datagrams to a different remote host, you must call the Connect method and specify the desired remote host. Use either of the other Send method overloads to send datagrams to a broadcast address.
So, in your server code:
1) Remove the empty catch block!
2) Use another udpClient.Send(byte[], int, IPEndPoint) overload that accepts the endpoint of the client - you get that via the reference you passed into Receive(ref IPEndPoint)
1: https://msdn.microsoft.com/en-us/library/08h8s12k(v=vs.110).aspx
I am trying to develop a C# based GUI program to receive the data from multiple TCP clients on a single server. All the clients should listen to the same port on the server and the server accepts the data from multiple clients, divide the receive data and display it in GUI.
I tried this console based program to receive the data from multiple clients on port 4000 on server. But i am not able to connect to the clients. For a single client using the specific ip address and port binding, its working fine. It just waiting for the multiple clients, and do not receive the data from the clients. Can you tell me the specific solution how to tackle this problem?
Here is my code:
using System;
using System.Net;
using System.Net.Sockets;
using System.Text;
using System.Threading;
public class ThreadedTcpSrvr
{
private TcpListener client;
public ThreadedTcpSrvr()
{
client = new TcpListener(4000);
client.Start();
while (true)
{
while (!client.Pending())
{
Thread.Sleep(100);
}
ConnectionThread newconnection = new ConnectionThread();
newconnection.threadListener = this.client;
Thread newthread = new Thread(new
ThreadStart(newconnection.HandleConnection));
newthread.Start();}
}
public static void Main()
{
ThreadedTcpSrvr server = new ThreadedTcpSrvr();
}
}
class ConnectionThread
{
public TcpListener threadListener;
private static int connections = 0;
public void HandleConnection()
{
int recv;
byte[] data = new byte[1024];
TcpClient client = threadListener.AcceptTcpClient();
NetworkStream ns = client.GetStream();
connections++;
Console.WriteLine("New client accepted: {0} active connections",
connections);
string welcome = "Welcome to the Server";
data = Encoding.ASCII.GetBytes(welcome);
ns.Write(data, 0, data.Length);
while (true)
{
data = new byte[1024];
recv = ns.Read(data, 0, data.Length);
if (recv == 0)
break;
ns.Write(data, 0, recv);
}
ns.Close();
client.Close();
connections--;
Console.WriteLine("Client disconnected: {0} active connections",
connections); }
}
P.S. I tried to capture the data through wireshark and i am able to capture the data.
I test those code independently working fine. Once I write it into user control and add it into application reference, and use it in the WPF, Visual studio turns to "Not Responding". This drives me crazy.
below is the user control code:
namespace ServerUserContorl
{
/// <summary>
/// Interaction logic for UserControl1.xaml
/// </summary>
public partial class UserControl1 : UserControl
{
public Socket server;
public Socket Command_Listening_Socket; //used to listen for connections for exchanging commands between server and mobile
public Socket Interaction_Listening_Socket1;// designed for receiving information from mobile
public Socket Interaction_Listening_Socket2;// designed for sending information to mobile
public Socket Interaction_Receiving_Socket;// receiving
public Socket Interaction_Sending_Socket;// sending
public UserControl1()
{
IPAddress local = IPAddress.Parse("134.129.125.126");
IPEndPoint iepCommand = new IPEndPoint(local, 8080);// IP end point for command listening socket
IPEndPoint iepReceiving = new IPEndPoint(local, 8090);// IP end point for receiving socket
IPEndPoint iepSending = new IPEndPoint(local, 9090);// Ip end point for sending socket
//part for command listening socket connection
server = new Socket(AddressFamily.InterNetwork, SocketType.Stream, ProtocolType.Tcp);
server.Bind(iepCommand);
server.Listen(20);
// part for receiving Socket
Interaction_Listening_Socket1 = new Socket(AddressFamily.InterNetwork, SocketType.Stream, ProtocolType.Tcp);
Interaction_Listening_Socket1.Bind(iepReceiving);
Interaction_Listening_Socket1.Listen(20);
// part for sending Socket
Interaction_Listening_Socket2 = new Socket(AddressFamily.InterNetwork, SocketType.Stream, ProtocolType.Tcp);
Interaction_Listening_Socket2.Bind(iepSending);
Interaction_Listening_Socket2.Listen(20);
while (true)
{
// Here is three blocks for accepting the new client,
// once client connect to the command listening socket,
// pass the command listening socket to the threadService class
// and start a thread for receiving the userID
Command_Listening_Socket = server.Accept();
Interaction_Receiving_Socket = Interaction_Listening_Socket1.Accept();
Interaction_Sending_Socket = Interaction_Listening_Socket2.Accept();
threadService service = new threadService(Command_Listening_Socket,Interaction_Receiving_Socket,Interaction_Sending_Socket);
Thread userCommand = new Thread(service.userCommand);
userCommand.Start();
Debug.WriteLine("thread starts");
}
}
}
}
using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
using System.Net.Sockets;
using System.Net;
using System.Diagnostics;
using System.Threading;
namespace ServerUserContorl
{
class CommunicationThread
{
public Socket Interaction_Receiving_Socket, Interaction_Sending_Socket;
public CommunicationThread(Socket receiving, Socket sending)
{
Interaction_Receiving_Socket = receiving;
Interaction_Sending_Socket = sending;
}
// connect with iep2 9090, clientCom1,clientCommunication1
public void sendThread()
{
Debug.WriteLine("In the SendThread method");
byte[] bytes = new byte[1024];
string greeting = "hello, this is the message from the server.";
bytes = System.Text.Encoding.ASCII.GetBytes(greeting);
Debug.WriteLine("the byte is " + bytes);
int i = 0;
while (i < 10)
{
Interaction_Sending_Socket.Send(bytes);
Thread.Sleep(1000);
i++;
}
Debug.WriteLine("send is successful");
// clientCommunication1.Close();
}
//8080
public void receiveThread()
{
int i = 0;
string data = null;
Debug.WriteLine("In the receive method");
byte[] bytes = new byte[1024];
while ((i = Interaction_Receiving_Socket.Receive(bytes)) != 0)
{
data = System.Text.Encoding.ASCII.GetString(bytes, 0, i);
Debug.WriteLine("receive from the client " + data);
}
//clientCommunication.Close();
}
}
}
using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
using System.Diagnostics;
using System.Net.Sockets;
using System.Threading;
namespace ServerUserContorl
{
class threadService
{
public Socket client;
//public Socket clientCommunication;
public string status;
public Socket Interaction_Receiving_Socket, Interaction_Sending_Socket;
public static int connections = 0;
int i = 0;
public threadService(Socket client,Socket receiving, Socket sending)
{
this.client = client;
Interaction_Receiving_Socket = receiving;
Interaction_Sending_Socket = sending;
}
public void userCommand()
{
string data = null;
byte[] bytes = new byte[1024];
if (client != null)
{
connections++;
}
Debug.WriteLine("new client connects, {0} connections", connections);
while ((i = client.Receive(bytes)) != 0)
{
data = System.Text.Encoding.ASCII.GetString(bytes, 0, i);
status = data;
Debug.WriteLine("receive from client: " + status);
if (status == "1")
{
CommunicationThread communication = new CommunicationThread(Interaction_Receiving_Socket,Interaction_Sending_Socket);
Thread newSendThread = new Thread(communication.sendThread);
newSendThread.Start();
Debug.WriteLine("start the communication thread--status 1");
// CommunicationThread communication = new CommunicationThread();
Thread newReceiveThread = new Thread(communication.receiveThread);
newReceiveThread.Start();
Debug.WriteLine("start the communication thread--status 2");
}
}
}
}
}
In the WFP, I only add it:
xmlns:myControl="clr-namespace:ServerUserContorl;assembly=ServerUserContorl"
<myControl:UserControl1>
Visual Studio's Designer has to call the control's constructor when you add the control, which means the Designer is going into the while(true) loop in the constructor.
First: Do not put an infinite loop in your control's constructor. EVER. If you need something to poll endlessly, that should be handled in your program's main or, better yet, in a separate thread. Until the constructor finishes the control can't be referenced by other objects, so you need to let the constructor finish.
Second: If you have code in your constructor you want the Designer to skip, you can do this:
using System.ComponentModel;
public MyControl()
{
// code that Designer should run
if (LicenseManager.UsageMode == LicenseUsageMode.DesignTime)
return;
// code that Designer should not run
}