Hello everyone I am very new to Visual Studio, C# programming, and Windows Form Applications.
My need is very simple - I want to create my own small program to listen to data being sent by a GPS device over UDP. I do not need to communicate, just listen and see the data on the screen!
Something that works exactly the same as this :
http://sockettest.sourceforge.net/ (see 'UDP' tab)
My GPS device has an IP of 192.168.1.1 and sends a sting of numbers every 1 second, continuously, transmitting on UDP 25.255.255.255:5017.
All the examples on the internet seems to focus on 2-way communicate, client and server chat windows etc. There is a lot of confusing terminology like synchronous and a-synchronous, client, server, UDP, TCP, binding.
I just want an even more simplified program than the above example, where I can type in the port number 5017, click Start Listening, and then straight away works!
All advice and code examples very gratefully received!!
Many thanks,
Jon
I now have it working, and can receive data in a textbox in the UI!
I use button_start_Click to open the port and start receiving. However, I cannot get button_stop_Click to work. How can you stop/close/disconnect/endReceive using button click?
public Form1()
{
InitializeComponent();
}
private void button_start_Click(object sender, EventArgs e)
{
Client = new UdpClient(Convert.ToInt32(textBox_port.Text));
Client.BeginReceive(DataReceived, null);
}
private void DataReceived(IAsyncResult ar)
{
IPEndPoint ip = new IPEndPoint(IPAddress.Any, Convert.ToInt32(textBox_port.Text));
byte[] data;
try
{
data = Client.EndReceive(ar, ref ip);
if (data.Length == 0)
return; // No more to receive
Client.BeginReceive(DataReceived, null);
}
catch (ObjectDisposedException)
{
return; // Connection closed
}
// Send the data to the UI thread
this.BeginInvoke((Action<IPEndPoint, string>)DataReceivedUI, ip, Encoding.UTF8.GetString(data));
}
private void DataReceivedUI(IPEndPoint endPoint, string data)
{
txtLog.AppendText("[" + endPoint.ToString() + "] " + data + Environment.NewLine);
}
private void button_stop_Click(IAsyncResult ar) // NOT WORKING!! AGH!
{
IPEndPoint ip = new IPEndPoint(IPAddress.Any, Convert.ToInt32(textBox_port.Text));
byte[] data;
data = Client.EndReceive(ar, ref ip);
Client.Close();
}
Run the same code in background worker and then you can cancel the background worker anytime using backgroundworker.cancelasync().
Hope this helps.
Related
I am currently creating an Unity Android application (GearVR) that could receive UDP packets send with broadcast on the Wi-Fi.
Unfortunately I can't receive any packet in my application.
Here is the script which I attached to a 3d game object.
public class UDPSceneScript : MonoBehaviour {
Thread udpListeningThread;
Thread udpSendingThread;
public int portNumberReceive;
UdpClient receivingUdpClient;
private void initListenerThread()
{
portNumberReceive = 5000;
Console.WriteLine("Started on : " + portNumberReceive.ToString());
udpListeningThread = new Thread(new ThreadStart(UdpListener));
// Run in background
udpListeningThread.IsBackground = true;
udpListeningThread.Start();
}
public void UdpListener()
{
receivingUdpClient = new UdpClient(portNumberReceive);
while (true)
{
//Listening
try
{
IPEndPoint RemoteIpEndPoint = new IPEndPoint(IPAddress.Any, 0);
//IPEndPoint RemoteIpEndPoint = new IPEndPoint(IPAddress.Broadcast, 5000);
// Blocks until a message returns on this socket from a remote host.
byte[] receiveBytes = receivingUdpClient.Receive(ref RemoteIpEndPoint);
if (receiveBytes != null)
{
string returnData = Encoding.ASCII.GetString(receiveBytes);
Console.WriteLine("Message Received" + returnData.ToString());
Console.WriteLine("Address IP Sender" + RemoteIpEndPoint.Address.ToString());
Console.WriteLine("Port Number Sender" + RemoteIpEndPoint.Port.ToString());
if (returnData.ToString() == "TextTest")
{
//Do something if TextTest is received
}
}
}
catch (Exception e)
{
Console.WriteLine(e.ToString());
}
}
}
void Start()
{
initListenerThread();
}
}
With the program SocketTest 3.0, I send "TextTest" to the address 255.255.255.255, port 5000
(I also tried by targeting directly the IP of the smartphone, it didn't work either)
Thanks in advance
Ran a quick test on your code and came to conclusion that your client code is fine. Replace all Console.WriteLine with Debug.Log and your will receive the data you are broadcasting. Console.WriteLine doesn't display anything in Unity's console.
If the problem is still there, please understand that some OS will block you from broadcasting to 255.255.255.255. If this is the case then get the IP of the device you are broadcasting from and replace the last octet with 255. Broadcast to that IP Address and that will also work just like 255.255.255.255.
For example, if your IP is 192.168.1.13, replace 13 with 255. You should broadcast to 192.168.1.255 in this case.
Finally, put the code below in your client script to make sure you kill that Thread when you click the Stop button in the Editor or you will have many problems during development.
void OnDisable()
{
if (udpListeningThread != null && udpListeningThread.IsAlive)
{
udpListeningThread.Abort();
}
receivingUdpClient.Close();
}
I'm working to make a Client/Server Application in C# using winsock Control. I done every thing in that but i stuck the place of sending data from client to server. In my program server always listen the client using the ip and port. I send the data from the client to server.
1)When click the Listen button on the server form it open the server where client is connect.
2)In Client form 1st i click the connect button for that the server is connected Gives an message (Connect Event: ip) for this message we easly know that the client is connected to the server.
3)Then we enter some data in the Send Data text Box then click Send Button to send the data to server and also save in client.
Code Below:
SERVER:
using System;
using System.Collections.Generic;
using System.Windows.Forms;
using System.Net;
using System.Threading;
using System.Net.Sockets;
namespace Server
{
public partial class Form1 : Form
{
public Form1()
{
InitializeComponent();
}
const string DEFAULT_SERVER = "ip";
const int DEFAULT_PORT = 120;
System.Net.Sockets.Socket serverSocket;
System.Net.Sockets.SocketInformation serverSocketInfo;
public string Startup()
{
IPHostEntry hostInfo = Dns.GetHostByName(DEFAULT_SERVER);
IPAddress serverAddr = hostInfo.AddressList[0];
var serverEndPoint = new IPEndPoint(serverAddr, DEFAULT_PORT);
serverSocket = new System.Net.Sockets.Socket(System.Net.Sockets.AddressFamily.InterNetwork, System.Net.Sockets.SocketType.Stream, System.Net.Sockets.ProtocolType.Tcp);
serverSocket.Bind(serverEndPoint);
return serverSocket.LocalEndPoint.ToString();
}
public string Listen()
{
int backlog = 0;
try
{
serverSocket.Listen(backlog);
return "Server listening";
}
catch (Exception ex)
{
return "Failed to listen" + ex.ToString();
}
}
public string ReceiveData()
{
System.Net.Sockets.Socket receiveSocket;
byte[] buffer = new byte[256];
receiveSocket = serverSocket.Accept();
var bytesrecd = receiveSocket.Receive(buffer);
receiveSocket.Close();
System.Text.Encoding encoding = System.Text.Encoding.UTF8;
return encoding.GetString(buffer);
}
private void Listen_Click(object sender, EventArgs e)
{
string serverInfo = Startup();
textBox1.Text = "Server started at:" + serverInfo;
serverInfo = Listen();
textBox1.Text = serverInfo;
//string datatosend = Console.ReadLine();
//SendData(datatosend);
serverInfo = ReceiveData();
textBox1.Text = serverInfo;
//Console.ReadLine();
}
private void winsock_DataArrival(object sender, AxMSWinsockLib.DMSWinsockControlEvents_DataArrivalEvent e)
{
ReceiveData();
Listen();
}
private void winsock_ConnectEvent(object sender, EventArgs e)
{
Listen();
}
}
}
This all are work perfectly But here my problem is that i get data form the client to server at only one time. When i send data again from the client to the server its not working and gives me some Message like
Additional information: Only one usage of each socket address
(protocol/network address/port) is normally permitted
In the server form
serverSocket.Bind(serverEndPoint);
Please someone help me to solve my problem.
Thank you.
Try this. It helps you
delegate void AddTextCallback(string text);
public Form1()
{
InitializeComponent();
}
private void ButtonConnected_Click(object sender, EventArgs e)
{
ThreadPool.QueueUserWorkItem(new WaitCallback(ServerHandler));
}
private void ServerHandler(object state)
{
TcpListener _listner = new TcpListener(IPAddress.Parse("12.2.54.658"), 145);
_listner.Start();
AddText("Server started - Listening on port 145");
Socket _sock = _listner.AcceptSocket();
//AddText("User from IP " + _sock.RemoteEndPoint);
while (_sock.Connected)
{
byte[] _Buffer = new byte[1024];
int _DataReceived = _sock.Receive(_Buffer);
if (_DataReceived == 0)
{
break;
}
AddText("Message Received...");
string _Message = Encoding.ASCII.GetString(_Buffer);
AddText(_Message);
}
_sock.Close();
AddText("Client Disconnected.");
_listner.Stop();
AddText("Server Stop.");
}
private void AddText(string text)
{
if (this.listBox1.InvokeRequired)
{
AddTextCallback d = new AddTextCallback(AddText);
this.Invoke(d, new object[] { text });
}
else
{
this.listBox1.Items.Add(text);
}
}
I'm also have the same problem like you on last month but i solve that using this Receive multiple different messages TcpListener C# from stackoverflow. This helps me lot hope it helps to solve your problem also.
I'm not 100% sure you understand TCP sockets so here goes.
When you use a TCP listener socket you first bind to a port so that clients have a fixed, known point to connect to. This reserves the port for your socket until you give it up by calling Close() on that socket.
Next you Listen in order to begin the process of accepting clients on the port you bound to. You can do both this and the first step in one but as you haven't I haven't here.
Next you call Accept(). This blocks (halts execution) until a client connects and then it returns a socket which is dedicated to communication with that client. If you want to allow another client to connect, you have to call Accept() again.
You can then communicate with your client using the socket that was returned by Accept() until you're done, at which point you call Close() on that socket.
When you're done listening for new connections you call Close() on your listener socket.
However when you press your listen button the following happens:
You bind correctly, you begin listening correctly and then your call to ReceiveData() blocks on the Accept call until a client is received. You then receive some data (though this is TCP so that might not be the whole data!) and then you instantly close the connection to your client.
I presume to get the error you're getting you must then press listen again on your server. This therefore restarts the whole listener socket and when you get to bind to the port the second time your previous listener is still bound to it and thus the call fails because something's already allocated on that port.
Solution wise you need to keep the socket returned from the Accept() call open until you're done with it. Have the client handle the close by calling the Shutdown() method on their socket or establish some convention for marking the end of communication.
You're also going to run into trouble when you try and have multiple users connected and so at some point you're either going to require threads or some asynchronous sockets but I feel that's out the scope of this question.
I suggest you do not use AxMSWinsockLib.. Have a look at socket example given here where it shows how to create a client socket and server socket - https://msdn.microsoft.com/en-us/library/kb5kfec7(v=vs.110).aspx AND this one - https://msdn.microsoft.com/en-us/library/6y0e13d3(v=vs.110).aspx
I have 6 devices, price checkers. I have a project which the client in a supermarket will scan a product on this device and it will return the price of the product. I have managed to connect with one device, get the bar code and send data. But I can not seem to do to connect with multiple socket connection.
This is the code when I receive and send data:
Connecting with the device:
private void connect1(string adip, int porta)
{
try
{
IPEndPoint ip = new IPEndPoint(IPAddress.Parse(adip), porta);
connect1 = new Socket(AddressFamily.InterNetwork, SocketType.Stream, ProtocolType.Tcp);
connect1.Connect(ip);
}
catch (System.Net.Sockets.SocketException se)
{
MessageBox.Show(se.Message);
}
}
Getting the barcode:
private void getbarCode()
{
byte[] data = new byte[1024];
int receivedDataLength = lidhje.Receive(data);
numberCodeBar = Encoding.ASCII.GetString(data, 0, receivedDataLength);
}
Sending data to device:
private void sendData(string price1)
{
try
{
Object objData = price1;
byte[] price = System.Text.Encoding.ASCII.GetBytes(objData.ToString());
connect1.Send(price);
}
catch (System.Net.Sockets.SocketException se)
{
MessageBox.Show(se.Message);
}
}
I want to connect with multiple decives in the same time, and when someone scans a barcode to the device the software will return to this device the price. I have searched Google, here on stackoverflow and codeproject but no luck.
Any sample code will appreciate it. Thanks.
Yes you can create multiple sockets in order to communicate with clients concurrently. See associated links for sample code.
Whether or not your application will be a client or a server will depend on how the price checker expects to be communicated with.
To make your life easier, focus on making a synchronous solution work first. You should only use asynchronous code when you fully understand how it works.
Additional Reading
MSDN: Synchronous Client Socket Example
MSDN: Synchronous Server Socket Example
MSDN: Asynchronous Client Socket Example
MSDN: Asynchronous Server Socket Example
I am trying to write a graphical C# program that can communicate with my Node.js server.
I am using UdpClient class and I am able to send some messages to the server.
However, I don't know how to receive UDP packages from the server.
JavaScript and Windows Form Widgets are event-driven, but UdpClient class in C# doesn't have any convenient events related to data reception.
Also, I don't know where to put the code of package reception. Most of online examples are console program and my program is GUI based.
I want my program to continuously listen at a port and when a package comes in, the program can capture the package and display its content in a TextBox.
Any suggestions ?
You can listen to a port asynchronously using BeginReceive. It works in GUI applications too - just remember to send the data to the UI thread before interacting with the UI.
This example is from a WinForms application. I've put a multiline textbox on the form called txtLog.
private const int MyPort = 1337;
private UdpClient Client;
public Form1() {
InitializeComponent();
// Create the UdpClient and start listening.
Client = new UdpClient(MyPort);
Client.BeginReceive(DataReceived, null);
}
private void DataReceived(IAsyncResult ar) {
IPEndPoint ip = new IPEndPoint(IPAddress.Any, MyPort);
byte[] data;
try {
data = Client.EndReceive(ar, ref ip);
if (data.Length == 0)
return; // No more to receive
Client.BeginReceive(DataReceived, null);
} catch (ObjectDisposedException) {
return; // Connection closed
}
// Send the data to the UI thread
this.BeginInvoke((Action<IPEndPoint, string>)DataReceivedUI, ip, Encoding.UTF8.GetString(data));
}
private void DataReceivedUI(IPEndPoint endPoint, string data) {
txtLog.AppendText("[" + endPoint.ToString() + "] " + data + Environment.NewLine);
}
Recently, I was given an assignment...
"To develop a Windows Forms application which can be installed on various windows machines at an office or enterprise. There would be a database in just one machine(ALPHA machine).. This database would be used by applications on other Beta machines to access data. The application would itself manage to check if it is an Alpha or a Beta (Has Database file with it?) and hence has to act as a server or a client."
I can do everything except the Network and Inter-Application Communication requirements. So, I started to learn Socket Programming over the Internet and I have gone through this link...
The idea I am working on is...
To have the client send the message to server.
To have the server accept this message and put this message in queue.
Read the message to get Client's IP Address and the its Request for Data.
Apply this request on database and get the result.
Convert the result in string.
Send it to the requesting client.
I can manage to perform steps 3,4 & 5. I am stuck on 1, 2 & 6.
Towards this...
I have created a function for Server as well as for client who return the Sockets when called. I create a separate function as I like my code to be clean, tidy and understandable after years.
Check my code below...
For Server...
private Socket GetServerReady()
{
IPEndPoint RemoteEP = new IPEndPoint(IPAddress.Any, 8000);
Socket newSock = new Socket(AddressFamily.InterNetwork, SocketType.Stream, ProtocolType.Tcp);
newSock.Connect(RemoteEP);
newSock.Listen(10);
return (newSock);
}
You will notice there is no Accept() method anywhere, This is because I wish to call it like below for further use...
Socket CltSock = GetServerReady().Accept();
The Code for Client is...
private Socket GetClientReady()
{
IPEndPoint RemoteEP = new IPEndPoint(IPAddress.Parse(txtBxHost2.Text.Trim()), 8000);
Socket ServerSock = new Socket(AddressFamily.InterNetwork, SocketType.Stream, ProtocolType.Tcp);
ServerSock.Connect(RemoteEP);
return (ServerSock);
}
Finally, The questions are....
"Where is the appropriate place to call the functions I wrote above?"
"Should I call the Server and Client Function in Form_Load() Event?"
"What must be the next step towards my main intention which is point 1,2 & 6 mentioned above?"
I don't expect the full code that I can just copy as it is. Just the correct procedure and a little detail over the concept would do.
I would be using just a single PC for testing purpose. Also, another limitation is, It would all be coded in a single application. I don't want to write two separate applications for client & server.
I hope I made it all clear for you to understand.
Thanks a Lot.
Awaiting the response.
I was struggling to get things done and somehow managed to get the solution.
Below is my solution:
Server Side code:
(I put this code in a function which loops back the execution if any exception is caught)
private void Looper()
{
int i = 0;
int AttemptCount = 1;
while (i == 0)
{
try
{
TcpListener tL = new TcpListener(Network.GetLocalIPAddress(), 56009);
tL.Start(10);
Socket tS = tL.AcceptSocket();
if (tS.Connected)
{
NetworkStream nS = new NetworkStream(tS);
StreamReader Reader = new StreamReader(nS);
Output = Reader.ReadToEnd().Trim();
Reader.Close();
nS.Close();
tS.Close();
tL.Stop();
//If Done, End Execution
i = 1;
}
else
{
MessageBox.Show("The connection to the client is broken or failed..!!\n\nPlease check connection and try again.","Error",MessageBoxButtons.OK,MessageBoxIcon.Error);
}
}
catch (SystemException ex)
{
//If Not, Loop Execution Again
if (MessageBox.Show("Exception: " + ex.Message + "\n\nAttempt Count: " + AttemptCount + "\n\nDo you want to terminate the transmission?", "Error", MessageBoxButtons.YesNo, MessageBoxIcon.Error) == DialogResult.Yes)
{
i = 1;
ResetTimer.Stop();
}
else
{
i = 0;
AttemptCount++;
}
}
}
}
When above function is called, The server waits to accept any incoming socket. If there is any error somewhere due to port re-usage or anything, It loops back itself and resets the server. (So, we don't have to manually call the server function again & again.)
Once the server accepts any incoming socket, the execution ends up successfully. Lot's of time we don't want to keep invoking server even after a successful reception. So, I, instead of calling this function in a button "click_event", I called it in a timer Tick_Event. So, the human need is eliminated at server side.
This leads to a problem. Once the server starts waiting to accept, It is in blocking mode.
It hangs all the processes and controls in same thread. So, I moved the call to above function to BackgroundWorker's "Do_Work" Event.
Check below Code:
private void GetServerReady()
{
if (!bW.IsBusy)
{
bW.RunWorkerAsync();
txtBxHistory.Text += "\r\n" + Output;
}
}
private void bW_DoWork(object sender, DoWorkEventArgs e)
{
Looper();
}
private void ResetTimer_Tick(object sender, EventArgs e)
{
GetServerReady();
}
"bW" is "BackgroundWorker".
"Output" is a variable I defined globally.
The reason we need a variable is that,
BackgroundWorker has its own thread to execute the code placed in its "Do_Work" Event. So, a TextBox from our application's thread can't be used by BackgroundWorker to store the received output. Doing this to a variable and then setting TextBox's Text property to this variable does the trick.
Client Side code:
private void btnSend_Click(object sender, EventArgs e)
{
TcpClient socketForServer;
try
{
socketForServer = new TcpClient(txtBxDestIP.Text.Trim(), 56009);
}
catch
{
MessageBox.Show("Failed to connect to server at " + txtBxDestIP.Text.Trim() + ":999", "Error", MessageBoxButtons.OK, MessageBoxIcon.Error);
return;
}
NetworkStream networkStream = socketForServer.GetStream();
StreamWriter streamWriter = new System.IO.StreamWriter(networkStream);
try
{
string InputString;
InputString = Network.GetLocalIPAddress() + ": " + txtBxData.Text;
streamWriter.Write(InputString);
streamWriter.Flush();
socketForServer.Close();
txtBxHistory.Text += "\r\nMe: " + txtBxData.Text.Trim();
txtBxData.Clear();
}
catch
{
MessageBox.Show("Exception reading from Server.", "Error", MessageBoxButtons.OK, MessageBoxIcon.Error);
}
streamWriter.Close();
networkStream.Close();
socketForServer.Close();
}
"txtBxDestIP" is a TextBox having the Destination IP address as Text.
"txtBxData" is a TextBox having the text to be sent.
This code works flawless for me. With above solution I can achieve all my motives from step 1 to 6 (Mentioned in the question above.)
I hope it helps others too. Please suggest if there is a better and efficient way to perform this.
Thanks.
Regards.