UDP send and receive between two programs in specific ports - sockets

I have a complete program that communicates via UDP protocol. Program runs on a PC with ip 192.168.1.9. When I send specific data, this program responds.
code for sending:
var client = new UdpClient();
IPEndPoint destination = new IPEndPoint(IPAddress.Parse("192.168.1.9"), 1531);
IPAddress localIp = IPAddress.Parse("192.168.1.3");
IPEndPoint source = new IPEndPoint(localIp, 1530);
client.Client.Bind(source);
client.Connect(destination);
byte[] send_buffer = { 170, 170, 0, 0, 1, 1, 86 };
client.Send(send_buffer, send_buffer.Length);
Wireshark captures:
Screen
But my application does not detect anything:
UdpClient listener = new UdpClient(1530);
IPAddress ip = IPAddress.Parse("192.168.1.3");
IPEndPoint groupEP = new IPEndPoint(IPAddress.Any, 1530);
byte[] receive_byte_array;
while (!done)
{
Console.WriteLine("Waiting for broadcast");
receive_byte_array = listener.Receive(ref groupEP);
}
I need to capture communications from 192.168.9 to 192.168.1.3 on port 1530.

Your sender is binding to local IP 192.168.1.3 on port 1530 as its source, and then sending data to remote IP 192.168.1.9 on port 1531 as the destination.
Your receiver is binding to local IP 0.0.0.0 on port 1530 for receiving data, and then filtering out any inbound data that was NOT sent from remote port 1530 (which it is).
The data is not being sent to the port that the receiver is reading on.
To fix that, you need to either:
change your receiver to bind to port 1531 instead of port 1530:
UdpClient listener = new UdpClient(1531);
change your sender to send the data to port 1530 instead of port 1531:
IPEndPoint destination = new IPEndPoint(IPAddress.Parse("192.168.1.9"), 1530);

Related

Connecting two computers in different networks using socket and Port forwarding

I have set up a simple client-server communication code and it works well in my computer when my computer itself acts as a server and the client.
Now I am trying to run this same code on two different computers in different networks( different locations) where my computer will act as a server and my friend's computer as a client.
I have done port forwarding in my router as well as in my friend's router for the port which we are trying to communicate. We both have set up a static IP in our internal network behind the router. We both had shutdown the firewall while running the code.
I am running my code on Jupiter notebook and the same is my friend too.
here is my server code:
import socket
import threading
HEADER = 64
PORT = 5064
SERVER = '0.0.0.0'
ADDR = (SERVER, PORT)
FORMAT = 'utf-8'
DISCONNECT_MESSAGE = "quit"
Receive_from_client = "get info"
server = socket.socket(socket.AF_INET,socket.SOCK_STREAM)
server.bind(ADDR)
def handle_client(conn, addr):
print("\n" + f"[NEW Connection] detected from IP: {addr[0]} & Port:{addr[1]} ")
conn.send(f"connected to server {ADDR}".encode(FORMAT))
connected =True
while connected:
msg_length = conn.recv(HEADER).decode(FORMAT) # decode the msg from byte to utf-8 format
if msg_length:
msg_length = int(msg_length)
msg = conn.recv(msg_length).decode(FORMAT)
if msg == DISCONNECT_MESSAGE:
connected = False
print(f" [Client][{addr}] {msg}")
print("Your session is disconnected")
break
if msg == Receive_from_client:
print("\n" + f"Send your msg to client with IP: {addr[0]}")
thread = threading.Thread(target = send2client, args = (conn, addr))
thread.start()
print(f" [Client][{addr}] {msg}")
conn.send(f"Msg received by server with IP:{addr[0]}".encode(FORMAT))
conn.close()
server.close()
def start():
server.listen()
print("\n"+ f"[LISTENING] Server is listening from IP: {SERVER} ")
while True:
conn, addr = server.accept()
thread = threading.Thread(target = handle_client, args = (conn, addr))
thread.start()
Here is the client code
import socket
import threading
HEADER = 64
PORT = 5064
FORMAT = 'utf-8'
DISCONNECT_MESSAGE = "quit"
SERVER = '103.192.207.250' # SERVERS public IP
ADDR = (SERVER, PORT)
client = socket.socket(socket.AF_INET,socket.SOCK_STREAM)
client.connect(ADDR)
def send2server():
while True:
msg = input()
message = msg.encode(FORMAT)
msg_lenght = len(message)
send_length = str(msg_lenght).encode(FORMAT)
send_length += b' '*(HEADER - len(send_length))
client.send(send_length)
client.send(message)
print(client.recv(2048).decode(FORMAT))
if msg == DISCONNECT_MESSAGE:
print("session closed")
client.close()
def start():
print("\n"+ f"[LISTENING] client is listening from IP: {ADDR} ")
send2server()
I have opened the port by going on windows firewall defender and selecting new inbound and outbound rules to open 5064 TCP port.
but still, the code doesn't works..
my server keeps waiting for connection and the client-side after few seconds of running gives this error:
TCP error code 10060: A connection attempt failed because the connected party did not properly respond after a period of time, or established connection failed because connected host has failed to respond
Even while my server is listening from port 5064 when I scan this port to check if the port is open or not it says closed.
How do I check if the port I have forwarded is for sure open and also how do I get this thing work?
I have tried all of this and if there is any other thing I am missing please tell. I am struggling to get this work for the past 3 days.

NetCore IPV6 socket connection fails on linux-arm

I am trying to establish an IPV6 socket connection with net-core 3.0 on a linux-arm platform (raspberry pi).
At the time when I try to bind the socket to the local ethernet adapter an Exception ((22): Invalid argument [fe80::211c:bf90:fbbf:9800]:5400) is thrown.
When i try the same on my windows development machine (with a different link-local ip), everything works fine.
IPV4 socket connection is also possible on both, my windows development machine and on the target linux-arm platform.
To the source code:
I used the socket example of microsoft as a base and changed the IPV4 into an IPV6 address.
The exception is thrown after the "Bind" method.
Here is the client side code:
//definet the target endpoint
IPAddress ipAddress;
IPAddress.TryParse("fe80::211c:bf90:fbbf:9800", out ipAddress);
IPEndPoint remoteEP = new IPEndPoint(ipAddress, 5400);
// Create a TCP/IP socket.
Socket sender = new Socket(ipAddress.AddressFamily ,SocketType.Stream, ProtocolType.Tcp);
//bind to the local network interface
IPAddress localIp;
IPAddress.TryParse("fe80::833:e68b:32ee:4c39", out localIp);
EndPoint localEndPoint = new IPEndPoint(IPAddress.IPv6Any, 0);
sender.Bind(localEndPoint);
// Connect the socket to the remote endpoint. Catch any errors.
try
{
sender.Connect(remoteEP);
Console.WriteLine("Socket connected to {0}",
sender.RemoteEndPoint.ToString());
The input of Ron was in fact the missing part. Hence the target endpoint IpAddress has to provided with the ScopeId (NIC Nr).
//definet the target endpoint
IPAddress ipAddress;
IPAddress.TryParse("fe80::211c:bf90:fbbf:9800", out ipAddress);
ipAddress.ScopeId = scopeId;
IPEndPoint remoteEP = new IPEndPoint(ipAddress, 5400);
To the scope ID of the first link local address for example this code can be used:
private static long GetScopeIdForHostLinkLocal()
{
IPAddress firstLinkLocal = null;
var info = NetworkInterface.GetAllNetworkInterfaces();
foreach (NetworkInterface nic in info)
{
var ipProps = nic.GetIPProperties();
var uniAddresses = ipProps.UnicastAddresses;
foreach (UnicastIPAddressInformation addressInfo in uniAddresses)
{
if (addressInfo.Address.IsIPv6LinkLocal)
{
firstLinkLocal = addressInfo.Address;
break;
}
}
if (firstLinkLocal != null)
{
break;
}
}
if (firstLinkLocal != null)
{
return firstLinkLocal.ScopeId;
}
else
{
return -1;
}
}

Create UDP client socket without socket listening

I'm using the standard way, shown in many examples, to create a UDP socket in C++, keep it alive and keep sending stuff over it.
I only call sendto. I never call recvfrom. In this code fragment I only use sendto once and then sleep for 5 seconds:
C code:
static int do_the_rest( int sock )
{
struct sockaddr_in server_addr;
bzero(&server_addr,sizeof(server_addr));
server_addr.sin_family = AF_INET;
server_addr.sin_addr.s_addr=inet_addr("192.168.32.32");
server_addr.sin_port=htons(32000);
char sendline[100];
bzero(sendline,sizeof(sendline));
const struct sockaddr * addr = (const struct sockaddr*)&server_addr;
sendto(sock,sendline,sizeof(sendline),0,addr,sizeof(server_addr));
sleep( 5 );
return 0;
}
int main(int argc, char**argv)
{
int sock;
sock=socket(AF_INET,SOCK_DGRAM,0);
if( sock < 0 ) {
perror( "socket" );
return 1;
}
int ret = do_the_rest( sock );
close( sock );
return ret;
}
Now, if I run "netstat -na", I can identify that the system seems to listen on the local port of the socket (I remove the lines in my program that print the local port, for clarity):
netstat -na:
Active Internet connections (servers and established)
Proto Recv-Q Send-Q Local Address Foreign Address State
...
udp 0 304 0.0.0.0:53735 0.0.0.0:*
When I try something similar in Java, I also seem to get some listening, although it looks a bit different (perhaps IPv6?):
Java code:
import java.io.*;
import java.net.*;
class Udp {
public static void main(String[] args) throws Throwable {
DatagramSocket sock = new DatagramSocket(null);
try {
InetAddress ipAddress = InetAddress.getByName("192.168.32.32");
byte[] sendData = new byte[50000];
DatagramPacket sendPacket = new DatagramPacket(
sendData, sendData.length, ipAddress, 32000);
sock.send(sendPacket);
Thread.sleep(5000);
} finally {
sock.close();
}
}
}
netstat -na:
Active Internet connections (servers and established)
Proto Recv-Q Send-Q Local Address Foreign Address State
...
udp 0 0 :::37053 :::*
I understand this is done in order to support a possible recvfrom (receive in Java) that may follow. However, is there a way to tell the socket not to listen to incoming packets at all?
Thanks
Now, if I run "netstat -na", I can identify that the system seems to listen on the local port of the socket
UDP sockets have a kernel buffer for incoming messages. This buffer is maintained by the kernel regardless whether you call recv/recvfrom/recvmsg from user-space code.
You can use shutdown() with its how parameter set to SHUT_RD to disable reads on the socket, which may have the intended behavior of stopping the listening, maybe even freeing the kernel's receive buffer. But the receive port has to remain allocated for the socket's lifetime, as it is used as the source port for the outgoing packets you are sending with sendto(). You cannot avoid that.
It is not only 'listening' on that port, it is sending via that port. The port allocation is required. The socket gets bound to a port as soon as you call sendto(), unless it is already bound.

How to force client in UDP to open port when sending with sendto

I have simple server and client in UDP (WinSocks/C++).
I send datagram client -> server via sendto, and reply from server to client using the ip and port obtained from recvfrom function.
I found out that:
Every sendto from client is being sent from different port
When trying to reply from server Windows returns WSAECONNRESET (which mean that port is closed - http://support.microsoft.com/kb/263823)
How can I properly answer client from server (ie force port binding on client when sending using sendto?)
Edit: Adding some source code:
bool InitClient()
{
internal->sock = socket(PF_INET, SOCK_DGRAM, 0);
char8 yes = 1;
setsockopt(internal->sock, SOL_SOCKET, SO_REUSEADDR, &yes, sizeof(int32));
return internal->sock != -1;
}
void Send(const IpAddress & target, const uint16 port, const char8 * data, int32 size )
{
sockaddr_in trgt;
memset(&trgt, 0, sizeof(trgt));
trgt.sin_family = AF_INET;
trgt.sin_port = htons(port);
trgt.sin_addr.s_addr = target.GetRaw();
if(sendto(internal->sock, (const char8 *)data, size, 0, (PSOCKADDR)&trgt, sizeof(trgt)) == SOCKET_ERROR)
{
LOG("Network sending error: %d", WSAGetLastError());
}
}
Call the "bind" function to specify a local port to send from. Example of using port 4567 below. Make sure to check the return value from bind.Call this code after you create the socket.
sockaddr_in local = {};
local.family = AF_INET;
local.port = htons(4567);
local.addr = INADDR_ANY;
bind(internal->sock,(sockaddr*)&local, sizeof(local));
If you bind to port zero instead of 4567 then the os will pick a random port for you and use it for all subsequent send and receives. You can call getsockname to discover which port the os picked for you after calling bind.

DNS Client that is written Using C Sockets

I just want to write DNS client program using C sockets that
takes three arguments: a query name (e.g., host name or domain name) and a query type (A, or NS, or MX), and DNS server name. Print out the responses in the answer section of the DNS record received.
I know there is a command getaddrinfo..
but I just want to connect to lookup table and then
get the DNS server name...
so when i give the input ./a.out www.google.com A 144.20.190.70
it will show something similar to this:
Server: 144.20.190.70
Address: 144.20.190.70#53
Non-authoritative answer:
Name : www.google.com
Canonical name : www.l.google.com
Name : www.l.google.com
Address : 74.125.19.104
Name : www.l.google.com
Address : 74.125.19.105
Name : www.l.google.com
Address : 74.125.19.106
Name : www.l.google.com
Address : 74.125.19.147
Name : www.l.google.com
Address : 74.125.19.99
Name : www.l.google.com
Address : 74.125.19.103
Yes you need to see Bev.net.dns class that Rob-philpott made for .net
Click Here
building requests to send to DNS servers is not easy but once you can get the answer back from the server then you need to send it back to the browser and this is the bit i've got stuck on.
i listen on port 53/UDP and get the request and send it to the DNS server and get a valid responce but then i send that back to the browser using the remote client port as a UDP but the browser will not except the reply.
Robs code is real easy to use as shown below "Resolver.Lookup" and i just neded to add a bit so that the original byte array sent from the DNS server as saved in Resolver.Message ready to send back to the browser.
public void Listen()
{
receiveSocket = new Socket(AddressFamily.InterNetwork, SocketType.Dgram, ProtocolType.Udp );
receiveEndPoint = new IPEndPoint(IPAddress.Any, receivePort); receiveSocket.Bind(receiveEndPoint);
receivePort = (receiveSocket.LocalEndPoint as IPEndPoint).Port;
receiveBuffer = new byte[BufferSize];
receiveAsyncResult = receiveSocket.BeginReceiveFrom(receiveBuffer, 0, receiveBuffer.Length, SocketFlags.None, ref receiveEndPoint, new AsyncCallback(NetworkMessageReceivedCallback), receiveSocket);
}
public void NetworkMessageReceivedCallback(IAsyncResult asyncResult)
{
EndPoint remoteEndPoint = null;
byte[] bytes = null;
remoteEndPoint = new IPEndPoint(IPAddress.Any, 0); //Will contain the clients port
int bytesRead = receiveSocket.EndReceiveFrom(asyncResult, ref remoteEndPoint);
bytes = new Byte[bytesRead];
Buffer.BlockCopy(receiveBuffer, 0, bytes, 0, bytesRead);
//string ip = "208.67.222.222";
string ip = "192.168.1.254";
IPAddress dnsServer = IPAddress.Parse(ip);
Response R = Resolver.Lookup(bytes, dnsServer);
receiveSocket.SendTo(R.Message , remoteEndPoint);//127.0.0.1
receiveSocket.Close();
Listen();
}