Create UDP client socket without socket listening - sockets

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.

Related

I need help to get data sent from an instrument via udp protocol

i have an instrument that measures so2 and i have a standard program that makes me see the data, but i need to connect the instrument to a server and send all the data to a database. I used wireshark to see how it comunicate with the software, but i don't understand what method to use to make my program. Here i have the wireshark dump:
the red circle indicates the measure that the instrument made.
P.S. sorry for my bad eng
So i solved my question as i'm about to show:
i made a listener and a caller;
caller:
`from socket import socket, AF_INET, SOCK_DGRAM
SERVER_IP = '192.168.1.99'
PORT_NUMBER = 53700
SIZE = 1024
print ("Test client sending packets to IP {0}, via port {1}\n".format(SERVER_IP, PORT_NUMBER))
mySocket = socket( AF_INET, SOCK_DGRAM )
mySocket.bind(('192.168.1.100', 57806))
while True:
data = bytes.fromhex('014630303430335230303102313103')
mySocket.sendto(data,(SERVER_IP,PORT_NUMBER))
exit()`
listener:
`from socket import socket, gethostbyname, AF_INET, SOCK_DGRAM
import sys
PORT_NUMBER = 57806
SIZE = 1024
hostName = gethostbyname( '' )
mySocket = socket( AF_INET, SOCK_DGRAM )
mySocket.bind( (hostName, PORT_NUMBER) )
print ("Test server listening on port {0}\n".format(PORT_NUMBER))
while True:
(data,addr) = mySocket.recvfrom(SIZE)
print (data)
sys.ext()`
i saw on wireshark that if i sent a request packet copied from the ones that i already have, the instrument would give me back the response; so i setupped a listener on the a choosen port, and now i get all the data!
the highlighted packet is the one i sent from the caller script.

Reset a TCP socket connection from application

How to reset an accepted socket in application level either with IO::Socket::INET in perl or in C?
There is a programm binding, listening on a TCP port, and accepts a client connection, after that it reads and writes some data.
If I simply close or shutdown the socket, TCP layer gracefully terminates (with FIN packet), rather than, I'd generate an RST packet.
You didn't specify the exact OS you are using. I found that Linux does have an API call which will reset a TCP connection, I have no idea how portable it is. The way to do it is to use the connect system call on the already connected socket but this time with family AF_UNSPEC.
After you have reset a socket that way it is even possible to connect the socket again with another connect call.
int main(int argc, char** argv)
{
int fd = socket(AF_INET6, SOCK_STREAM, 0);
while (1) {
struct sockaddr_in6 sockaddr = {
.sin6_family = AF_INET6,
.sin6_port = htons(80),
.sin6_flowinfo = 0,
.sin6_scope_id = 0,
};
struct timespec s = {
.tv_sec = 2,
.tv_nsec = 0,
};
/* Connect to port 80 on localhost */
inet_pton(AF_INET6, "::1", &sockaddr.sin6_addr.s6_addr);
connect(fd, (struct sockaddr*)&sockaddr,sizeof(sockaddr));
nanosleep(&s, NULL);
/* Reset previously connected socket */
sockaddr.sin6_family = AF_UNSPEC;
connect(fd, (struct sockaddr*)&sockaddr,sizeof(sockaddr));
nanosleep(&s, NULL);
}
}

Raw socket: unexpected IP header added when sending self-made IP/TCP packets

I want to use raw socket to send TCP packets which is a full IP packet(so the packet has IP header, TCP header and TCP payload, but has no ethernet header. The IP source and destination addresses are in a WLAN, 192.168.0.105 and 192.168.0.103), with the following codes
int on;
on = 0;
if ((sendfd = socket(AF_INET, SOCK_RAW, IPPROTO_RAW)) < 0) {
perror("raw socket");
exit(1);
}
if (setsockopt(sendfd, IPPROTO_IP, IP_HDRINCL, &on, sizeof(on)) < 0) {
perror("setsockopt");
exit(1);
}
nr_bytes = sendto(sendfd, packet, ip_len, 0, (struct sockaddr*)&client_addr, addr_len);
I use TCPdump to capture the sent-out packet and notice it has added an additional IP header to the IP packet, and the IP protocol number is 255(ip->ip_p is 255). So it has two IP headers(with same pair of src and dst IP), which is unexpected.
what are the problems? thank you!
Using IPPROTO_RAW implicitly enables the option IP_HDRINCL.
In your call to setsockopt() you disable IP_HDRINCL again because you set on = 0.
Try removing the setsockopt() or setting on = 1.

Is it possible to use the same port and ip address?

I created a TCP server program which binds, listen and accepting a connection from the specific ip address and port number.
During the first connection : Server is accepting a SYN packet from the client and sending an ACK back to the client. Later getting a ACK from the client. Finally Client is RST with the server.
During the second connection the client is sending a SYN packet to the slave but there is no ACK from the server.
I think there is no binding is possible during the second connection with the same ip address and port number.
Is it possible to bind with the SAME ip address and port number in the second connection ?
server :
SOCKET sock;
SOCKET fd;
uint16 port = 52428;
// I am also using non blocking mode
void CreateSocket()
{
struct sockaddr_in server, client; // creating a socket address structure: structure contains ip address and port number
WORD wVersionRequested;
WSADATA wsaData;
int len;
int iResult;
u_long iMode = 1;
printf("Initializing Winsock\n");
wVersionRequested = MAKEWORD (1, 1);
iResult = WSAStartup (wVersionRequested, &wsaData);
if (iResult != NO_ERROR)
printf("Error at WSAStartup()\n");
// create socket
sock = socket(AF_INET, SOCK_STREAM, IPPROTO_TCP);
if (sock < 0) {
printf("Could not Create Socket\n");
//return 0;
}
printf("Socket Created\n");
iResult = ioctlsocket(sock, FIONBIO, &iMode);
if (iResult < 0)
printf("\n ioctl failed \n");
// create socket address of the server
memset( &server, 0, sizeof(server));
// IPv4 - connection
server.sin_family = AF_INET;
// accept connections from any ip adress
server.sin_addr.s_addr = htonl(INADDR_ANY);
// set port
server.sin_port = htons(52428);
//Binding between the socket and ip address
if(bind (sock, (struct sockaddr *)&server, sizeof(server)) < 0)
{
printf("Bind failed with error code: %d", WSAGetLastError());
}
//Listen to incoming connections
if(listen(sock, 10) == -1){
printf("Listen failed with error code: %d", WSAGetLastError());
}
printf("Server has been successfully set up - Waiting for incoming connections");
for(;;){
len = sizeof(client);
fd = accept(sock, (struct sockaddr*) &client, &len);
if (fd < 0){
printf("Accept failed");
closesocket(sock);
}
//echo(fd);
printf("\n Process incoming connection from (%s , %d)", inet_ntoa(client.sin_addr),ntohs(client.sin_port));
//closesocket(fd);
}
}
TCP connections are identified by four parameters:
Local IP
Local port
Remote IP
Remote port
The server normally uses the same Local IP and port for all its connections (e.g. an HTTP server listens on port 80 for all connection). Each connection from a client will have a different Remote IP and/or Remote port, and these resolve the ambiguity.
When the server closes all of its connected sockets, the TCB sticks around for several minutes in a TIME_WAIT state. This normally prevents a process from binding to the port, because you can't bind to a local IP/port that has any associated TCBs. If you want to restart the server and bind to the same port and address that it just used for connections, you need to use the SO_REUSEADDR socket option to get around this. See:
Socket options SO_REUSEADDR and SO_REUSEPORT, how do they differ? Do they mean the same across all major operating systems?
for details of this.

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.