Programming sockets in R to receive a UDP stream

In Python, I can write code for programming sockets to receive a data stream over UDP.

However, how can I get the equivalent code in R to do the same?

import socket, traceback host = '' port = 5555 s = socket.socket(socket.AF_INET, socket.SOCK_DGRAM) s.setsockopt(socket.SOL_SOCKET, socket.SO_REUSEADDR, 1) s.setsockopt(socket.SOL_SOCKET, socket.SO_BROADCAST, 1) s.bind((host, port)) counter = 1500 while counter > 0: counter -= 1 try: message, address = s.recvfrom(8192) message = message.decode() data = message.split(",") print(data) except (KeyboardInterrupt, SystemExit): raise except: traceback.print_exc() 

In R, I tried with the code below, which failed. I understand that I need to mention somewhere that this is UDP and thatโ€™s all, but I canโ€™t find these settings.

I need to get a "stream" of data from a device. Do I need an R server for this?

x86_64-pc-linux-gnu platform
os linux-gnu
version.string R version 3.2.3 (2015-12-10) RStudio Version 1.0.44

 server <- function(){ while(TRUE){ writeLines("Listening...") con <- socketConnection(host="localhost", port = 5555, blocking=TRUE,server=TRUE, open="r+") data <- readLines(con, 1) print(data) close(con) } } server() 
+8
r
source share
2 answers

JF,

I would like to write your code directly in C / C ++ and include R in your program through

Using the above approach, you can create a package that mimics the functionality of python or simply wrap Python code inside an RCPP package directly. This last point is discussed in the next tutorial.

I hope that the explanation above and the sample code below will help you in the right direction.

Rcpp Code Example:

Listener.R

 setwd("~/dev/stackoverflow/40896072") # install.packages("installr") # require(installr) # install.Rtools() # install.packages("Rcpp") # # Test and Verify # Rcpp::evalCpp("2+2") Rcpp::sourceCpp( file = "./listener.cc") listen() 

Listener.cc

 /* listener.c - a datagram socket 'server' * simply displays message received then dies! */ #include <stdio.h> #include <stdlib.h> #include <unistd.h> #include <errno.h> #include <string.h> #include <sys/types.h> #include <sys/socket.h> #include <netinet/in.h> #include <arpa/inet.h> #include <Rcpp.h> using namespace Rcpp; #define MYPORT 5555 /* the port users connect to */ #define MAXBUFLEN 100 // [[Rcpp::export]] int listen() { int sockfd; struct sockaddr_in my_addr; /* info for my addr ie server */ struct sockaddr_in their_addr; /* client address info */ socklen_t addr_len; ssize_t numbytes; char buf[ MAXBUFLEN]; printf( "Running\n"); if( (sockfd = socket( AF_INET, SOCK_DGRAM, 0)) == -1) { perror( "Listener socket"); exit( 1); } memset( &my_addr, 0, sizeof( my_addr)); /* zero struct */ my_addr.sin_family = AF_INET; /* host byte order ... */ my_addr.sin_port = htons( MYPORT); /* ... short, network byte order */ my_addr.sin_addr.s_addr = INADDR_ANY; /* any of server IP addrs */ if( bind( sockfd, (struct sockaddr *)&my_addr, sizeof( struct sockaddr)) == -1) { perror( "Listener bind"); exit( 1); } addr_len = sizeof( struct sockaddr); if( (numbytes = recvfrom( sockfd, buf, MAXBUFLEN - 1, 0, (struct sockaddr *) &their_addr, &addr_len)) == -1) { perror( "Listener recvfrom"); exit( 1); } printf( "Got packet from %s\n", inet_ntoa( their_addr.sin_addr)); printf( "Packet is %zd bytes long\n", numbytes); buf[ numbytes] = '\0'; /* end of string */ printf( "Packet contains \"%s\"\n", buf); close( sockfd); return 0; } 

Client.R

 setwd("~/dev/stackoverflow/40896072") # install.packages("installr") # require(installr) # install.Rtools() # install.packages("Rcpp") # # Test and Verify # Rcpp::evalCpp("2+2") Rcpp::sourceCpp( file = "./client.cc") client() 

Client.cc

 /* client.c - a datagram 'client' */ #include <stdio.h> #include <stdlib.h> #include <unistd.h> #include <errno.h> #include <string.h> #include <sys/types.h> #include <sys/socket.h> #include <netinet/in.h> #include <arpa/inet.h> #include <netdb.h> /* for gethostbyname() */ //#include <Rcpp.h> //using namespace Rcpp; #define PORT 5555 /* server port the client connects to */ // [[Rcpp::export]] int client() { socklen_t sockfd; ssize_t numbytes; struct hostent *he; struct sockaddr_in their_addr; /* server address info */ /* resolve server host name or IP address */ if ( (he = gethostbyname("localhost")) == NULL ) { perror( "Talker gethostbyname"); exit( 1); } if ( (sockfd = socket( AF_INET, SOCK_DGRAM, 0)) == -1) { perror( "Talker socket"); exit( 1); } memset( &their_addr,0, sizeof(their_addr) ); /* zero struct */ their_addr.sin_family = AF_INET; /* host byte order .. */ their_addr.sin_port = htons( PORT); /* .. short, netwk byte order */ their_addr.sin_addr = *( (struct in_addr *)he -> h_addr); if( (numbytes = sendto( sockfd, "Hello", strlen("Hello"), 0, (struct sockaddr *) &their_addr, sizeof( struct sockaddr))) == -1) { perror( "Talker sendto"); exit( 1); } printf( "Sent %zd bytes to %s\n", numbytes, inet_ntoa( their_addr.sin_addr)); close( sockfd ); return 0; } 

Runtime output

enter image description here

+5
source share

Is RMarkdown useful for you to write your Python code and run it?

 --- title: "socket_prog" output: html_document --- ```{python} import socket, traceback host = '' port = 5555 s = socket.socket(socket.AF_INET, socket.SOCK_DGRAM) s.setsockopt(socket.SOL_SOCKET, socket.SO_REUSEADDR, 1) s.setsockopt(socket.SOL_SOCKET, socket.SO_BROADCAST, 1) s.bind((host, port)) counter = 1500 while counter > 0: counter -= 1 try: message, address = s.recvfrom(8192) message = message.decode() data = message.split(",") print(data) except (KeyboardInterrupt, SystemExit): raise except: traceback.print_exc() ``` 
+1
source share

All Articles