I have this code in a console app:
using System.Text;
using System.Diagnostics;
using System.Net.Sockets;
using System.Net;
namespace ConsoleApplication3
{
class Program
{
static void Main(string[] args)
{
byte[] data = ASCIIEncoding.ASCII.GetBytes("test message");
string IP = "192.168.1.22";
int Port = 2390;
IPEndPoint endPoint = new IPEndPoint(IPAddress.Parse(IP), Port);
Socket client = new Socket(AddressFamily.InterNetwork, SocketType.Dgram, ProtocolType.Udp);
SocketAsyncEventArgs socketEventArg = new SocketAsyncEventArgs();
socketEventArg.RemoteEndPoint = endPoint;
socketEventArg.SetBuffer(data, 0, data.Length);
client.SendToAsync(socketEventArg);
Debug.WriteLine("sent");
}
}
}
and this code in the Windows Universal App:
using Windows.UI.Xaml;
using Windows.UI.Xaml.Controls;
using System.Net;
using System.Net.Sockets;
using System.Diagnostics;
using System.Text;
namespace App6
{
public sealed partial class MainPage : Page
{
public MainPage()
{
this.InitializeComponent();
byte[] data = ASCIIEncoding.ASCII.GetBytes("test message");
string IP = "192.168.1.22";
int Port = 2390;
IPEndPoint endPoint = new IPEndPoint(IPAddress.Parse(IP), Port);
Socket client = new Socket(AddressFamily.InterNetwork, SocketType.Dgram, ProtocolType.Udp);
SocketAsyncEventArgs socketEventArg = new SocketAsyncEventArgs();
socketEventArg.RemoteEndPoint = endPoint;
socketEventArg.SetBuffer(data, 0, data.Length);
client.SendToAsync(socketEventArg);
Debug.WriteLine("sent");
}
}
}
As you can see the content of both is nearly identical.
The IP I set it to send to is a program I'm running on a different computer that I have confirmed works. When I run the console application, it displays the data I sent properly on the program on the other computer, and the console application prints out "sent" on the debug console as it should. The Universal Windows App similarly prints out "sent", however the packet never reaches the other computer.
I checked using WireShark (a network analysis/packet sniffing tool) and it appears that when I use the console application, a UDP packet is sent, but when I use the Universal Windows app, no UDP packets are found.
I am running both programs from Visual Studio 2015 in debug mode, and I can't think of any reason why it wouldn't be working.
Any suggestions or ideas would be helpful!
Just a guess - have you added the internetClient capability to your app? https://msdn.microsoft.com/en-us/library/windows/apps/mt280233.aspx
Related
I have searched everywhere but couldn't find as they are all answering to send message to all clients. What I want to achieve is multiple clients request to server to request data from another client and other client sends data to server telling it that data is for requesting client and so. I don't know how to achieve this. I'm new to this.
What I want to achieve:
I have tried with Data sending client to listen and requesting client to connect to it and transfer data. I have achieved this on local network but to make it work online it needs port forwarding and my user will be a lot of different people so port forwarding is not possible for every user. So I can rent a server which will act as a center of transfer. I programmed a test server in console which will listen to a server IP:port X and accept new clients and their data on port X and forward it to server IP:port Y but what this does is send data to all clients on port Y. I cannot send it to clients public ip address directly for obvious reasons. I understand that all the requesting clients are connected to port Y but I cannot create and assign new ports to all the clients interacting. So I want a way to determine how to request and receive the data without the need of assigning or creating new ports to different clients on same server.
What I have tried:
Server code
using System;
using System.Collections.Generic;
using System.IO;
using System.Linq;
using System.Net;
using System.Net.Sockets;
using System.Text;
using System.Threading;
using System.Threading.Tasks;
namespace Test___server
{
class server
{
public static string serverIP = "192.168.0.102";
static void Main(string[] args)
{
Thread listenSendingThread = new Thread(listenSending);
listenSendingThread.IsBackground = true;
listenSendingThread.Start();
Thread listenReceivingThread = new Thread(listenReceiving);
listenReceivingThread.IsBackground = true;
listenReceivingThread.Start();
Console.ReadKey();
}
public static List<TcpClient> listSending = new List<TcpClient>();
public static List<TcpClient> listReceiving = new List<TcpClient>();
public static TcpClient clientSending = null;
private static void listenSending()
{
TcpListener listenerSending = new TcpListener(IPAddress.Parse(serverIP), 5319);
listenerSending.Start();
Console.WriteLine("Server listening to " + serverIP + ":5319");
while(true)
{
clientSending = listenerSending.AcceptTcpClient();
listSending.Add(clientSending);
Console.WriteLine("Sender connection received from " + clientSending.Client.RemoteEndPoint);
}
}
private static void send()
{
StreamWriter sw = new StreamWriter(clientSending.GetStream());
sw.WriteLine(message);
sw.Flush();
Console.WriteLine("Message sent!");
}
public static string message = string.Empty;
private static void listenReceiving()
{
TcpListener listener = new TcpListener(IPAddress.Parse(serverIP), 0045);
listener.Start();
Console.WriteLine("Server listening to " + serverIP + ":0045");
while (true)
{
TcpClient client = listener.AcceptTcpClient();
listReceiving.Add(client);
Console.WriteLine("Receiver connection received from " + client.Client.RemoteEndPoint);
StreamReader sr = new StreamReader(client.GetStream());
message = sr.ReadLine();
send();
}
}
}
}
Requesting client code
using System;
using System.Collections.Generic;
using System.IO;
using System.Linq;
using System.Text;
using System.Threading.Tasks;
namespace Test____admin
{
class admin
{
static void Main(string[] args)
{
Console.WriteLine("Begin");
string serverIP = "192.168.0.102";
System.Net.Sockets.TcpClient clientSocket = new System.Net.Sockets.TcpClient();
clientSocket.Connect(serverIP, );
Console.WriteLine("Connected");
while (true)
{
Console.WriteLine("Reading");
StreamReader sr = new StreamReader(clientSocket.GetStream());
Console.WriteLine("Message: " + sr.ReadLine());
}
}
}
}
Request satisfying client code
using System;
using System.Collections.Generic;
using System.IO;
using System.Linq;
using System.Net.Sockets;
using System.Text;
using System.Threading.Tasks;
namespace Test___client
{
class client
{
public static string serverIP = "192.168.0.102";
static void Main(string[] args)
{
clientConnect();
}
private static void clientConnect()
{
try
{
TcpClient client = new TcpClient(serverIP, 0045);
StreamWriter sw = new StreamWriter(client.GetStream());
sw.WriteLine("Karan!");
sw.Flush();
}
catch (Exception ex)
{
Console.WriteLine(ex.ToString());
}
}
}
}
You are using a very low-level API, and doing it the right way is challenging. Instead, try YARP as a reverse proxy. The requesting client should notify the reverse proxy about the desired destination client. One option is sending the destination client name in the request header. You will also need to split a single server request into multiple client requests, then merge their responses into a single one. You can achieve it by implementing Transphorms.
I'm not sure this approach applies to your situation because clients should implement server API using REST, Grpc or any other supported technology.
I am trying to send an udp packet from one computer to another in a local network. One computer is running Windows 10, other Ubuntu 18.04.
The code I have so far is this:
Server:
using System;
using System.Net.Sockets;
using System.Net;
namespace udpTest
{
class Program
{
static void Main(string[] args)
{
string hostName = Dns.GetHostName();
string ip = Dns.GetHostEntry(hostName).AddressList[0].ToString();
IPAddress ipadd = IPAddress.Parse(ip);
var serverEndPoint = new IPEndPoint(ipadd, 20020);
var udp = new UdpClient(ipadd.ToString(), 20020);
while (true) {
var recvData = udp.ReceiveAsync().Result;
System.Console.WriteLine($"received: {recvData.Buffer}");
}
}
}
}
Client:
using System;
using System.Net.Sockets;
using System.Net;
namespace C_
{
class Program
{
static void Main(string[] args)
{
var udp = new UdpClient();
var bytes = BitConverter.GetBytes(420);
var i = udp.SendAsync(bytes, bytes.Length, "fe80::7077:8d67:4984:c9bc%43", 20020 ).Result;
System.Console.WriteLine($"sent: {i}");
}
}
}
(I changed the ipv6 address a bit but format is exactly the same).
I get no errors when sending or anything, it just goes through but the server does not catch it. I have no idea what I am doing wrong. So any pointers would be most appreciated.
Edit: updated code works within lan, but not outside LAN.
Client:
static void Main(string[] args)
{
var udp = new UdpClient("192.168.1.117", 20020);
var bytes = BitConverter.GetBytes(420);
var i = udp.SendAsync(bytes, bytes.Length).Result;
System.Console.WriteLine($"sent: {i}");
}
Server:
static void Main(string[] args)
{
var serverEndPoint = new IPEndPoint(IPAddress.Any, 20020);
var udp = new UdpClient(serverEndPoint);
while (true) {
var recvData = udp.ReceiveAsync().Result;
System.Console.WriteLine($"received: {recvData.Buffer}");
}
}
first try IPAddress.Any since using the first IP address from Dns.GetHostEntry(hostName).AddressList[0].ToString(); is not guaranteed to be the IPv6 address you are using, specially if the computer has more than one network adapter.
Second is using the serverEndPoint you created for the UdpClient constructor
// Use IPAddress.Any
IPAddress ipadd = IPAddress.Any;
var serverEndPoint = new IPEndPoint(ipadd, 20020);
// Use the serverEndPoint for the UP
var udp = new UdpClient(serverEndPoint);
Third, check the server's firewall settings and make sure you allow incoming UDP messages on port 20020 (by default on both Windows and Ubuntu it is not allowed). And check the client firewall settings and make sure outgoing UDP messages on port 20020 are allowed (by default on both Windows and Ubuntu it is allowed).
I am trying to receive socket communication with C # on Unity.
The following unityRecieve.cs will result in an error if Send.py is interrupted.
Send.py
import socket
import random
HOST = '127.0.0.1'
PORT = 50007
client = socket.socket(socket.AF_INET, socket.SOCK_DGRAM)
while True:
a = random.randrange(3)
result = str(a)
print(a)
client.sendto(result.encode('utf-8'),(HOST,PORT))
time.sleep(2.0)
unityRecieve.cs
using UnityEngine;
using System.Net;
using System.Net.Sockets;
using System.Text;
public class unityRecieve : MonoBehaviour
{
static UdpClient udp;
void Start()
{
int LOCA_LPORT = 50007;
udp = new UdpClient(LOCA_LPORT);
udp.Client.ReceiveTimeout = 100;
}
void Update()
{
IPEndPoint remoteEP = null;
byte[] data = udp.Receive(ref remoteEP);
string text = Encoding.UTF8.GetString(data);
Debug.Log(text);
}
}
https://jump1268.hatenablog.com/entry/2018/11/25/143459
How can I make unitiRecieve.cs keep running without giving an error message when Send.py is interrupted?
Not sure if you have considered exception handling. If you did not, this might point you in the right direction.
https://learn.microsoft.com/en-us/dotnet/csharp/language-reference/keywords/try-catch
I am a beginner in networking but I have to start with something, so I decided to create a chat app in visual studio 2010 using C# language (winforms).
I googled a lot about that and I've found almost exactly what I needed.
I found the following code samples (in C# - console):
http://msdn.microsoft.com/en-us/library/system.net.sockets.tcpclient.aspx
http://msdn.microsoft.com/en-us/library/system.net.sockets.tcplistener(v=VS.71).aspx
I want to create that application using TCP protocol (I don't know if there are easier ways to do that, but I understood the basics of TCP when I tried to create that chat in C#.
When I executed the code samples in the links above, they worked! So I tried to adapt those samples at my chat application.
My chat application consists actually of two apps: a server and a client. Both of them have the same GUI (two text boxes, a button and two labels for displaying whether the client is connected to the server).
textBox1 on the server/client app is the one that display the message sent by the client/server app.
In the textBox2 on the server/client app the user types a message and then presses the button to send the message to the client/server app.
Let me show you what I've tried until now:
This is the server application code.
using System;
using System.Collections.Generic;
using System.ComponentModel;
using System.Data;
using System.Drawing;
using System.Linq;
using System.Text;
using System.Windows.Forms;
using System.Net;
using System.Net.Sockets;
namespace Server_TCP_WINFORMS
{
public partial class Form1 : Form
{
//Int32 port = 13000;
IPAddress localAddr = IPAddress.Parse("127.0.0.1");
TcpListener server = new TcpListener(IPAddress.Parse("127.0.0.1"), 13000);
public Form1()
{
InitializeComponent();
server.Start();
}
byte[] bytes = new byte[256];
String data = null;
TcpClient client = new TcpClient();
bool sw = true;
int data_at_byte_level = 0;
private void Form1_Load(object sender, EventArgs e)
{
try
{
label2.Text = "Waiting for an incoming connection...";
if (!server.Pending())
{
label2.Text = "For moment, there are no connections requests!";
}
else
{
client = server.AcceptTcpClient();
label2.Text = "Connected!";
sw = false;
}
}
catch (SocketException xyz)
{
MessageBox.Show("Exception occured!");
}
if (sw == false)
{
NetworkStream stream = client.GetStream();
while ((data_at_byte_level = stream.Read(bytes, 0, bytes.Length)) != 0)
{
data = System.Text.Encoding.ASCII.GetString(bytes);
textBox1.Text += data;
data = null;
bytes = null;
}
}
}
private void button1_Click(object sender, EventArgs e)
{
String dataT;
if (textBox2.Text!=null && sw == false)
{
NetworkStream stream = client.GetStream();
dataT = textBox2.Text;
byte[] msg = System.Text.Encoding.ASCII.GetBytes(dataT);
stream.Write(msg, 0, msg.Length);
}
}
}
}
And this is the client application code:
using System;
using System.Collections.Generic;
using System.ComponentModel;
using System.Data;
using System.Drawing;
using System.Linq;
using System.Text;
using System.Windows.Forms;
using System.Net.Sockets;
using System.Net;
namespace Client_TCP_WINFORMS
{
public partial class Form1 : Form
{
TcpClient client = new TcpClient("127.0.0.1", 13000);
public Form1()
{
InitializeComponent();
label2.Text = "Conected to the server!";
}
private void button1_Click(object sender, EventArgs e)
{
NetworkStream stream = client.GetStream();
if (textBox2.Text != null)
{
String data_str = textBox2.Text;
Byte[] data_byte = System.Text.Encoding.ASCII.GetBytes(data_str);
stream.Write(data_byte, 0, data_byte.Length);
}
}
private void Form1_Load(object sender, EventArgs e)
{
Byte[] data_byte = new Byte[290];
int bytes;
string Data;
NetworkStream stream = client.GetStream();
bytes = stream.Read(data_byte, 0, data_byte.Length);
Data = System.Text.Encoding.ASCII.GetString(data_byte, 0, bytes);
textBox1.Text += Data;
}
}
}
I want that those two apps to behave in the following way: I start the server application then I start the client application. When both of them are open, I want them to be already connected (because it's simpler that way, I think).
Then, I want that both of them to be receptive which means that when the server (for example) sends a message to the client, the latter one should receive the message and display it. If the server send another message, the client should receive and display it too.
If the user (of the client or the user of the server) presses the send button, the application should send the message from the textBox2 to the other application. How can I do those things in windows forms?
I see in the code samples in console that there is a main loop where the server reads the message from the client. But what if the server wants to send a message too? If the send button is pressed, the event for the button_pressed occurs and then it sends the message, but when it finished sending the message, it goes back to the main loop?
Please excuse my english. I am not a native speaker.
Thank you respectfully.
"When both of them are open, I want them to be already connected (because it's simpler that way, I think)."
For this, you need to use UDP(User Datagram Protocol) rather than TCP
i'm trying to make an application for my laptop which in case i forgot to log off, i can use my smarthphone to log off by using a specific app for that. So i was thinking usually if you have a router... you have a problem cause you don't have the external ip which you can use, and the port. For that i used this function to get the external ip.
public string adresaIP()
{
UTF8Encoding utf8 = new UTF8Encoding();
WebClient clientWeb = new WebClient();
String adresaIP = utf8.GetString(clientWeb.DownloadData("http://bot.whatismyipaddress.com"));
return adresaIP;
}
But when i try to use te IpEndPoint it dosen't work it give's me an exception Error and i don't know were i did wrong.
using System;
using System.Collections.Generic;
using System.ComponentModel;
using System.Data;
using System.Drawing;
using System.Linq;
using System.Text;
using System.Windows.Forms;
using System.Net;
using System.Net.Sockets;
using System.IO;
namespace bluetooth_LogOff
{
public partial class Form1 : Form
{
static byte[] buffer { get; set; }
static Socket soket;
public Form1()
{
InitializeComponent();
try
{
string ip = adresaIP();
soket = new Socket(AddressFamily.InterNetwork, SocketType.Stream, ProtocolType.Tcp);
//soket.Bind(new IPEndPoint(IPAddress.Parse(ip),1234)); <<-- in this way dosen't work
soket.Bind(new IPEndPoint(IPAddress.Parse("127.0.0.1"),1234)); // <<- in this way it works....
soket.Listen(100);
Socket accept = soket.Accept();
buffer = new byte[accept.SendBufferSize];
int bytesRead = accept.Receive(buffer);
byte[] format = new byte[bytesRead];
for (int i = 0; i < bytesRead; i++)
{
format[i] = buffer[i];
}
string primescMesaj = Encoding.ASCII.GetString(format);
MessageBox.Show(primescMesaj);
soket.Close();
accept.Close();
}
catch (Exception messaj)
{
MessageBox.Show(messaj.ToString());
}
}
private void button1_Click(object sender, EventArgs e)
{
label1.Text = adresaIP();
}
public string adresaIP()
{
UTF8Encoding utf8 = new UTF8Encoding();
WebClient clientWeb = new WebClient();
String adresaIP = `utf8.GetString(clientWeb.DownloadData("http://bot.whatismyipaddress.com"));`
return adresaIP;
}
}
}
But the funny thing is if i put the addres like "127.0.0.1" It works, but if i put the string addres it dosen't
You cannot bind to the external address that address belongs to the router.
You should bind to address 0.0.0.0 (all addresses) on your laptop and configure your router to forward the laptop port (or use UPnP).
The reason you cannot access your laptop directly is because your router, like most routers is a NAT (network address translation) router. It allows several computers to hide behind a single IP address. So the router will have a public IP address and your laptop and other devices behind the router will have a private IP address (such as those in the range 192.168.x.x)
Most NAT routers can be configured with static port forwarding; i.e. the port in a specific private address is reflected in the same or a different port in the public IP.
This allows access to internal devices from the public internet. UPnP is a protocol that does the same thing, but does not require manual configuration on the router. UPnP is usually how P2P applications and some multi-player games gain public accessible ports without human intervention. It is also why UPnP may be considered a security hazard since the computer owner may not be aware of such forwarding.