Get list of all ipv4 and ipv6 under same hostname - c++

Suppose I have entries in /etc/hosts like:
10.10.64.225 HostName1
10.10.64.226 HostName1
10.10.64.227 HostName1
FE80:0000:0000:0000:0202:B3FF:FE1E:8329 HostName1
2001:0db8:85a3:0000:0000:8a2e:0370:7334 HostName1
Now I want a list of all IP's under same host name.
I am using getaddrinfo function.
test.c file:
#include <stdlib.h>
#include <sys/types.h>
#include <sys/socket.h>
#include <netdb.h>
#include <arpa/inet.h>
#include <string.h>
#include <stdio.h>
#include <errno.h>
int main(int argc, char *argv[])
{
struct addrinfo hints, *list, *curr;
int arg, errcode;
if (argc < 2 || !strcmp(argv[1], "-h") || !strcmp(argv[1], "--help")) {
fprintf(stderr, "\n");
fprintf(stderr, "Usage: %s [ -h | --help ]\n", argv[0]);
fprintf(stderr, " %s HOSTNAME ...\n", argv[0]);
fprintf(stderr, "\n");
return EXIT_FAILURE;
}
for (arg = 1; arg < argc; arg++) {
memset(&hints, 0, sizeof (hints));
hints.ai_family = PF_UNSPEC;
hints.ai_socktype = SOCK_STREAM;
errcode = getaddrinfo(argv[arg], NULL, &hints, &list);
if (errcode) {
fprintf(stderr, "%s: %s.\n", argv[arg], gai_strerror(errcode));
return EXIT_FAILURE;
}
for (curr = list; curr != NULL; curr = curr->ai_next) {
if (curr->ai_family == AF_INET) {
char addrbuf[INET_ADDRSTRLEN + 1];
const char *addr;
addr = inet_ntop(AF_INET, &(((struct sockaddr_in *)curr->ai_addr)->sin_addr), addrbuf, sizeof addrbuf);
if (addr == NULL) {
fprintf(stderr, "%s: %s.\n", argv[arg], strerror(errno));
return EXIT_FAILURE;
}
printf("%s: IPv4 = %s\n", argv[arg], addr);
} else
if (curr->ai_family == AF_INET6) {
char addrbuf[INET6_ADDRSTRLEN + 1];
const char *addr;
addr = inet_ntop(AF_INET6, &(((struct sockaddr_in6 *)curr->ai_addr)->sin6_addr), addrbuf, sizeof addrbuf);
if (addr == NULL) {
fprintf(stderr, "%s: %s.\n", argv[arg], strerror(errno));
return EXIT_FAILURE;
}
printf("%s: IPv6 = %s\n", argv[arg], addr);
}
}
freeaddrinfo(list);
}
return EXIT_SUCCESS;
}
Output:
./test HostName1
ks1: IPv4 = 10.10.64.225
ks1: IPv6 = FE80:0000:0000:0000:0202:B3FF:FE1E:8329
The issue in code is, it return only first IPV4 and first IPV6 address.
and I need a list of all IP's under same Host name.

Related

Providing default webpage called "index.html" to web browser

#include <stdio.h>
#include <stdlib.h>
#include <string.h>
#include <windows.h>
#include <stddef.h>
#include <process.h>
#include <fcntl.h>
#include <sys\stat.h>
#include <fstream>
#define OK_IMAGE "HTTP/1.0 200 OK\r\nContent-Type:image/gif\r\n\r\n"
#define OK_TEXT "HTTP/1.0 200 OK\r\nContent-Type:text/html\r\n\r\n"
#define NOTOK_404 "HTTP/1.0 404 Not Found\r\nContent-Type:text/html\r\n\r\n"
#define MESS_404 "<html><body><h1>FILE NOT FOUND</h1></body></html>"
#define BUF_SIZE 1024
#define PORT_NUM 80
int Count;
void handle_get(void *in_arg);
void do_end(void *server_s);
void main()
{
unsigned int server_s; // Server socket descriptor
struct sockaddr_in server_addr; // Server Internet address
unsigned int client_s; // Client socket descriptor
struct sockaddr_in client_addr; // Client Internet address
int addr_len; // Internet address length
WSADATA wsaData;
WSAStartup(MAKEWORD(1,1), &wsaData);
server_s = socket(AF_INET, SOCK_STREAM, 0);
server_addr.sin_family = AF_INET;
server_addr.sin_port = htons(PORT_NUM);
server_addr.sin_addr.s_addr = htonl(INADDR_ANY);
bind(server_s, (struct sockaddr *)&server_addr, sizeof(server_addr));
printf("HTTP Server Start.(Stop:ESC)\n");
if (_beginthread(do_end, 0, (void*)&server_s) < 0) {
printf("ERROR - Unable to create thread \n");
exit(1);
}
while(1)
{
listen(server_s, 50);
addr_len = sizeof(client_addr);
client_s = accept(server_s, (struct sockaddr*)&client_addr, addr_len);
if (client_s == -1)
{
printf("ERROR - Unable to create a socket \n");
exit(1);
}
Count++;
if (client_s == -1) {
if(server_s) printf("ERROR - Unable to create a socket \n");
exit(1);
}
if (_beginthread(handle_get, 0, (void *)client_s) < 0)
{
printf("ERROR - Unable to create a thread to handle the GET \n");
exit(1);
}
}
}
void handle_get(void *in_arg)
{
unsigned int client_s;
char in_buf[BUF_SIZE];
char out_buf[BUF_SIZE];
int fh;
int buf_len;
char command[BUF_SIZE];
char file_name[BUF_SIZE];
int retcode;
int i;
client_s = (unsigned int) in_arg;
retcode = recv(client_s, in_buf, BUF_SIZE, 0);
if (retcode <= 0)
{
printf("ERROR - Receive failed --- probably due to dropped connection \n");
Count--;
closesocket(client_s);
_endthread();
}
for (i=0; i<retcode; i++)
printf ("%c", in_buf[i]);
sscanf(in_buf, "%s %s \n", command, file_name);
if (strcmp(command, "GET") != 0) {
printf("ERROR - Not a GET --- received command = '%s' \n", command);
Count--;
closesocket(client_s);
_endthread();
}
if(file_name[1]=='\0') {
strcpy(file_name[1], "index.htm");
fh = open(file_name[1], O_RDONLY | O_BINARY, S_IREAD | S_IWRITE);
}
else
fh = open(&file_name[1], O_RDONLY | O_BINARY, S_IREAD | S_IWRITE);
if (fh == -1) {
printf("File '%s' not found --- sending an HTTP 404 \n", &file_name[1]);
strcpy(out_buf, NOTOK_404);
send(client_s, out_buf, strlen(out_buf), 0);
strcpy(out_buf, MESS_404);
send(client_s, out_buf, strlen(out_buf), 0);
Count--;
closesocket(client_s);
_endthread();
}
if (((file_name[1] == '.') && (file_name[2] == '.')) ||
(file_name[1] == '/') || (file_name[1] == '\\') ||
(file_name[2] == ':'))
{
printf("SECURITY VIOLATION --- trying to read '%s' \n", &file_name[1]);
Count--;
close(fh);
closesocket(client_s);
_endthread();
}
printf("Sending file '%s' \n\n\n", &file_name[1]);
if (strstr(file_name, ".gif") != NULL)
strcpy(out_buf, OK_IMAGE);
else
strcpy(out_buf, OK_TEXT);
send(client_s, out_buf, strlen(out_buf), 0);
while(!eof(fh)) {
buf_len = read(fh, out_buf, BUF_SIZE);
send(client_s, out_buf, buf_len, 0);
}
Count--;
close(fh);
closesocket(client_s);
_endthread();
}
void do_end(void *server_s)
{
unsigned int temp;
temp = *((unsigned int*)server_s);
while(getch()!=27);
while(Count);
*((unsigned int*)server_s) = 0;
printf("HTTP Server Stop.\n");
closesocket(temp);
WSACleanup();
exit(1);
This is a routine that allows the user to send the "index.htm" file first if the above if statement does not specify any file names. (If the current server has a file called "index.html" instead of this file, a problem occurs.)
file_name[1] contains the name of the requested file.
However, how can I provide a default page called "index.html" to a web browser if a file named "index.html" currently exists on the server and the user didn't name the file?
if(file_name[1]=='\0') {
strcpy(file_name[1], "index.htm");
fh = open(file_name[1], O_RDONLY | O_BINARY, S_IREAD | S_IWRITE);
}
Considering that it's Windows (given the #include <windows.h>), the easiest solution is to do nothing. index.html is found when opening index.htm, because the latter is the 8.3 name of index.html.
All you need to do is check the return value of sscanf(), which tells you how many tokens were read.

Multiple Broadcast Reception on Same port but different interfaces

I'm trying to build a little personal DHCP server to serve a specific scope if the broadcast is received on eth0 and another if received on wlan0 but I can't bind more than a single interface on the same address:port combination (255.255.255.255:67)
I heard about SO_REUSABLE but I have no idea about how to implement it and if of course it's the good way to do it
Actually this is my code :
#include <stdio.h>
#include <string.h>
#include <stdlib.h>
#include <arpa/inet.h>
#include <sys/socket.h>
#include <sys/ioctl.h>
#include <net/if.h>
#include <netinet/in.h>
#include <errno.h>
#include <fstream>
#include <iostream>
#include <vector>
#define BUFLEN 1024
#define PORT 67
using namespace std;
char *ipAddrFromInterface(char *apInterfaceName) //this function is not from me
{
return "255.255.255.255";
/*char *if_name = (char *) apInterfaceName;
struct ifreq ifr;
size_t if_name_len = strlen(if_name);
if(if_name_len < sizeof(ifr.ifr_name))
{
memcpy(ifr.ifr_name, if_name, if_name_len);
ifr.ifr_name[if_name_len] = 0;
}
else
printf("interface name is too long\n");
int fd = socket(AF_INET, SOCK_DGRAM, 0);
if(fd == -1)
printf("A => %s\n", strerror(errno));
if(ioctl(fd, SIOCGIFADDR, &ifr) == -1)
{
int temp_errno = errno;
close(fd);
printf("B => %s\n", strerror(temp_errno));
}
if(ioctl(fd, SIOCGIFADDR, &ifr) == -1)
{
int temp_errno = errno;
close(fd);
printf("C => %s\n", strerror(temp_errno));
}
close(fd);
struct sockaddr_in* ipaddr = (struct sockaddr_in*) &ifr.ifr_addr;
return inet_ntoa(ipaddr->sin_addr);*/
}
struct socketData
{
int sock;
sockaddr_in socket;
char *interfaceName;
};
void print(int i)
{
printf("%d\n", i);
fflush(stdout);
}
void server_receive_thread(vector<char*> aInterfaceList)
{
int socketIndex = 0;
struct sockaddr_in localSock;
int socketDescriptor; int socketLength;
vector<socketData> aSockets;
for( ; socketIndex < aInterfaceList.size(); socketIndex++)
{
socketData socketD;
char *apInterfaceName = aInterfaceList.at(socketIndex);
if((socketDescriptor = socket(AF_INET, SOCK_DGRAM, IPPROTO_UDP)) == -1)
{
printf("can't listen on interface %s... sleeping\n", apInterfaceName);
}
else
{
memset(&localSock, 0, sizeof(localSock));
localSock.sin_family = AF_INET;
localSock.sin_port = htons(PORT);
inet_aton(ipAddrFromInterface(apInterfaceName), &localSock.sin_addr);
setsockopt(socketDescriptor, SOL_SOCKET, SO_BINDTODEVICE, apInterfaceName, sizeof(apInterfaceName));
if(bind(socketDescriptor, (struct sockaddr *) &localSock, sizeof(localSock)) == -1)
{
printf("can't bind interface %s to listen on port %d... sleeping\n", apInterfaceName, PORT);
}
else
{
printf("bound to interface %s on port %d\n", apInterfaceName, PORT);
socketD.sock = socketDescriptor;
socketD.socket = localSock;
socketD.interfaceName = apInterfaceName;
aSockets.push_back(socketD);
}
}
}
fd_set master;
int fdMax = -1;
while(1)
{
FD_ZERO(&master);
for(int iSock = 0; iSock < aSockets.size(); iSock++)
{
socketData d = aSockets.at(iSock);
FD_SET(d.sock, &master);
if(d.sock > fdMax)
fdMax = d.sock;
}
printf("fdmax is : ");
print(fdMax);
if(select(fdMax + 1, &master, NULL, NULL, NULL) == -1)
print(2);
print(200);
for(int iSock = 0; iSock < aSockets.size(); iSock++)
{
socketData d = aSockets.at(iSock);
if(FD_ISSET(d.sock, &master))
print(3);
}
print(1);
}
}
int main()
{
std::vector<char*> interfaceList;
interfaceList.push_back("wlan0");
interfaceList.push_back("eth0");
server_receive_thread(interfaceList);
return 0;
}
You don't need a socket per interface. Just bind a single socket to 0.0.0.0 and the desired port. Then it will receive via all interfaces. You certainly can't, and don't need to, bind to 255.255.255.255.
Or, bind it to the single IP address that is connected to the scope you want to serve.

Socket send/recv return 0 on small data transfer

In my client:
numbytes = send(sockfd, argv[2], strlen(argv[2]), 0)
In my server:
numbytes = recv(new_fd, buf, MAXBUFLEN-1 , 0)
In both cases numbytes is 0, argv[2]="test" and MAXBUFLEN=100. I don't know why 0 bytes are being sent/received. I'm sending the data via cygwin to a vm.
Edit: I've tested the code with a separate client thats worked before and I get the same problem, so I assume the problem is with the server
Client:
$ ./talker.exe 155.26.37.55 test
argv[2]: test
talker: sent 0 bytes to 155.26.37.55
Server:
Maxbuflen: 100
listener: got packet from 155.26.37.55
listener: packet is 0 bytes long
listener: packet contains ""
Code Cient:
#include <stdio.h>
#include <stdlib.h>
#include <iostream>
#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>
#define SERVERPORT "4951" // the port users will be connecting to
int main(int argc, char *argv[])
{
int sockfd;
struct addrinfo hints, *servinfo, *p;
int rv;
int numbytes;
if (argc != 3) {
fprintf(stderr,"usage: talker hostname message\n");
exit(1);
}
memset(&hints, 0, sizeof hints);
hints.ai_family = AF_UNSPEC;
hints.ai_socktype = SOCK_STREAM;
if ((rv = getaddrinfo(argv[1], SERVERPORT, &hints, &servinfo)) != 0) {
fprintf(stderr, "getaddrinfo: %s\n", gai_strerror(rv));
return 1;
}
// loop through all the results and make a socket
for(p = servinfo; p != NULL; p = p->ai_next) {
if ((sockfd = socket(p->ai_family, p->ai_socktype,
p->ai_protocol)) == -1) {
perror("talker: socket");
continue;
}
if (connect(sockfd, p->ai_addr, p->ai_addrlen) == -1) {
close(sockfd);
perror("client: connect");
continue;
}
break;
}
if (p == NULL) {
fprintf(stderr, "talker: failed to bind socket\n");
return 2;
}
std::cout<<"argv[2] "<<argv[2]<<std::endl;
if ((numbytes = send(sockfd, argv[2], strlen(argv[2]), 0) == -1)) {
perror("talker: send");
exit(1);
}
freeaddrinfo(servinfo);
printf("talker: sent %d bytes to %s\n", numbytes, argv[1]);
close(sockfd);
return 0;
}
Code server:
#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>
#define MYPORT "4951" // the port users will be connecting to
#define MAXBUFLEN 100
#define BACKLOG 10
// get sockaddr, IPv4 or IPv6:
void *get_in_addr(struct sockaddr *sa)
{
if (sa->sa_family == AF_INET) {
return &(((struct sockaddr_in*)sa)->sin_addr);
}
return &(((struct sockaddr_in6*)sa)->sin6_addr);
}
int main(void)
{
int sockfd;
struct addrinfo hints, *servinfo, *p;
int rv;
int numbytes;
int new_fd;
socklen_t addr_size;
struct sockaddr_storage their_addr;
char buf[MAXBUFLEN];
char s[INET6_ADDRSTRLEN];
memset(&hints, 0, sizeof hints);
hints.ai_family = AF_UNSPEC; // set to AF_INET to force IPv4
hints.ai_socktype = SOCK_STREAM;
hints.ai_flags = AI_PASSIVE; // use my IP
if ((rv = getaddrinfo(NULL, MYPORT, &hints, &servinfo)) != 0) {
fprintf(stderr, "getaddrinfo: %s\n", gai_strerror(rv));
return 1;
}
// loop through all the results and bind to the first we can
for(p = servinfo; p != NULL; p = p->ai_next) {
if ((sockfd = socket(p->ai_family, p->ai_socktype,
p->ai_protocol)) == -1) {
perror("listener: socket");
continue;
}
int yes=1;
// lose the pesky "Address already in use" error message
if (setsockopt(sockfd,SOL_SOCKET,SO_REUSEADDR,&yes,sizeof(int)) == -1) {
perror("setsockopt");
exit(1);
}
if (bind(sockfd, p->ai_addr, p->ai_addrlen) == -1) {
close(sockfd);
perror("listener: bind");
continue;
}
if (listen(sockfd,BACKLOG) == -1){
close(sockfd);
perror("listener:listen");
continue;
}
break;
}
if (p == NULL) {
fprintf(stderr, "listener: failed to bind socket\n");
return 2;
}
freeaddrinfo(servinfo);
printf("listener: waiting to recv..\n");
while(1){
addr_size = sizeof their_addr;
if ((new_fd = accept(sockfd, (struct sockaddr *)&their_addr, &addr_size))==-1){
perror("accept");
exit(1);
}
printf("Maxbuflen: %d\n",MAXBUFLEN);
if ((numbytes = recv(new_fd, buf, MAXBUFLEN-1 , 0) == -1)) {
perror("recv");
exit(1);
}
printf("listener: got packet from %s\n",
inet_ntop(their_addr.ss_family,
get_in_addr((struct sockaddr *)&their_addr),
s, sizeof s));
printf("listener: packet is %d bytes long\n", numbytes);
buf[numbytes] = '\0';
printf("listener: packet contains \"%s\"\n", buf);
close(new_fd);
}
return 0;
}
recv() returns 0 when the socket has been closed by the other party, in this case your client.

Portable compact representation of IP address

I have a C++ program using the Berkley sockets API on Linux. I have one end of the connection sending two IP addresses to the client. I can represent these using inet_ntop() and inet_pton(), but this would make the message length 2*INET6_ADDRSTRLEN, which is 92 bytes. That seems a little much for two IP addresses. Is there a portable, compact binary representation of IP addresses (it must work with both IPv4 and IPv6).
If you have an addrinfo lying around, then send the .ai_addr and .ai_addrlen.
Try these two programs:
send_sockaddr.cc:
#include <sys/types.h> /* See NOTES */
#include <sys/socket.h>
#include <netdb.h>
#include <unistd.h>
#include <cstdio>
#include <cerrno>
#include <cstdlib>
int main (int ac, char **av) {
if(ac != 3) {
fprintf(stderr, "Usage: %s hostname portnumber\n", *av);
return 1;
}
struct addrinfo *res0;
struct addrinfo hints = { AI_CANONNAME, 0, SOCK_DGRAM };
int rc = getaddrinfo(av[1], av[2], &hints, &res0);
if(rc) {
fprintf(stderr, "%s/%s: %s\n", av[1], av[2], gai_strerror(rc));
return 1;
}
char *name = res0->ai_canonname;
for(struct addrinfo *res = res0; res; res=res->ai_next) {
fprintf(stderr, "%s: %04X/%04X/%04X ", name, res->ai_family, res->ai_socktype, res->ai_protocol);
int fd = socket(res->ai_family, res->ai_socktype, res->ai_protocol);
if(fd < 0) {
perror("socket");
continue;
}
rc = connect(fd, res->ai_addr, res->ai_addrlen);
if(rc < 0) {
perror("connect");
continue;
}
fprintf(stderr, "Connected (%d)\n", fd);
*(unsigned short*)res->ai_addr = htons(*(unsigned short*)res->ai_addr);
rc = send(fd, res->ai_addr, res->ai_addrlen, 0);
*(unsigned short*)res->ai_addr = ntohs(*(unsigned short*)res->ai_addr);
if(rc < 0) {
perror("send");
}
close(fd);
}
freeaddrinfo(res0);
}
listen_sockaddr.cc:
#include <sys/types.h>
#include <sys/socket.h>
#include <netdb.h>
#include <unistd.h>
#include <cstdio>
#include <cerrno>
#include <cstdlib>
#include <poll.h>
#include <vector>
#include <arpa/inet.h>
int main (int ac, char **av) {
if(ac != 2) {
fprintf(stderr, "Usage: %s portnumber\n", *av);
return 1;
}
struct addrinfo *res0;
struct addrinfo hints = { 0, 0, SOCK_DGRAM };
int rc = getaddrinfo(0, av[1], &hints, &res0);
if(rc) {
fprintf(stderr, "%s/%s: %s\n", av[1], av[2], gai_strerror(rc));
return 1;
}
char *name = res0->ai_canonname;
std::vector<pollfd> fds;
for(struct addrinfo *res = res0; res; res=res->ai_next) {
fprintf(stderr, "%s: ", name);
int fd = socket(res->ai_family, res->ai_socktype, res->ai_protocol);
if(fd < 0) {
perror("socket");
continue;
}
rc = bind(fd, res->ai_addr, res->ai_addrlen);
if(rc < 0) {
perror("bind");
continue;
}
fprintf(stderr, "Bound (%d)\n", fd);
fds.push_back(pollfd({fd, POLLIN}));
}
freeaddrinfo(res0);
while( (rc = poll( &fds[0], fds.size(), -1)) > 0 ) {
for(size_t i = 0; i < fds.size(); ++i) {
pollfd& pfd = fds[i];
if(!pfd.revents)
continue;
pfd.revents = 0;
union {
sockaddr s;
sockaddr_in sin;
sockaddr_in6 sin6;
} u;
rc = recv(pfd.fd, &u, sizeof u, 0);
if(rc < 0) {
perror("recv");
continue;
}
fprintf(stderr, "Received %d bytes\n", rc);
char str[256];
switch(ntohs(u.s.sa_family)) {
case AF_INET:
if(inet_ntop(AF_INET, &u.sin.sin_addr, str, sizeof str)) {
fprintf(stderr, "AF_INET %s\n", str);
} else {
fprintf(stderr, "AF_INET unknown\n");
}
break;
case AF_INET6:
if(inet_ntop(AF_INET6, &u.sin6.sin6_addr, str, sizeof str)) {
fprintf(stderr, "AF_INET6 %s\n", str);
} else {
fprintf(stderr, "AF_INET6 unknown\n");
}
break;
default:
fprintf(stderr, "UNKNOWN\n");
break;
}
}
}
}
Actually, IP addresses aren't numbers itself, so the byte representation would always follow Big-Endian. At least I don't know any platform where this is different. It's just not handled as a number, but as 4 bytes.

Can two applications communicate by UDP packets?

I'm looking for a way to ease the difficulty transferring data from one application/process to another, but should have some sort of error recovering capbility.
As UDP is an existing protocol that works well over network, I wonder if it can also be used by processes in the same OS(windows xp here) .
If yes can you provide some core code that illustrate this?
Read this http://beej.us/guide/bgnet/output/html/multipage/clientserver.html
listener.c
/*
** listener.c -- a datagram sockets "server" demo
*/
#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>
#define MYPORT "4950" // the port users will be connecting to
#define MAXBUFLEN 100
// get sockaddr, IPv4 or IPv6:
void *get_in_addr(struct sockaddr *sa)
{
if (sa->sa_family == AF_INET) {
return &(((struct sockaddr_in*)sa)->sin_addr);
}
return &(((struct sockaddr_in6*)sa)->sin6_addr);
}
int main(void)
{
int sockfd;
struct addrinfo hints, *servinfo, *p;
int rv;
int numbytes;
struct sockaddr_storage their_addr;
char buf[MAXBUFLEN];
socklen_t addr_len;
char s[INET6_ADDRSTRLEN];
memset(&hints, 0, sizeof hints);
hints.ai_family = AF_UNSPEC; // set to AF_INET to force IPv4
hints.ai_socktype = SOCK_DGRAM;
hints.ai_flags = AI_PASSIVE; // use my IP
if ((rv = getaddrinfo(NULL, MYPORT, &hints, &servinfo)) != 0) {
fprintf(stderr, "getaddrinfo: %s\n", gai_strerror(rv));
return 1;
}
// loop through all the results and bind to the first we can
for(p = servinfo; p != NULL; p = p->ai_next) {
if ((sockfd = socket(p->ai_family, p->ai_socktype,
p->ai_protocol)) == -1) {
perror("listener: socket");
continue;
}
if (bind(sockfd, p->ai_addr, p->ai_addrlen) == -1) {
close(sockfd);
perror("listener: bind");
continue;
}
break;
}
if (p == NULL) {
fprintf(stderr, "listener: failed to bind socket\n");
return 2;
}
freeaddrinfo(servinfo);
printf("listener: waiting to recvfrom...\n");
addr_len = sizeof their_addr;
if ((numbytes = recvfrom(sockfd, buf, MAXBUFLEN-1 , 0,
(struct sockaddr *)&their_addr, &addr_len)) == -1) {
perror("recvfrom");
exit(1);
}
printf("listener: got packet from %s\n",
inet_ntop(their_addr.ss_family,
get_in_addr((struct sockaddr *)&their_addr),
s, sizeof s));
printf("listener: packet is %d bytes long\n", numbytes);
buf[numbytes] = '\0';
printf("listener: packet contains \"%s\"\n", buf);
close(sockfd);
return 0;
}
talker.c
/*
** talker.c -- a datagram "client" demo
*/
#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>
#define SERVERPORT "4950" // the port users will be connecting to
int main(int argc, char *argv[])
{
int sockfd;
struct addrinfo hints, *servinfo, *p;
int rv;
int numbytes;
if (argc != 3) {
fprintf(stderr,"usage: talker hostname message\n");
exit(1);
}
memset(&hints, 0, sizeof hints);
hints.ai_family = AF_UNSPEC;
hints.ai_socktype = SOCK_DGRAM;
if ((rv = getaddrinfo(argv[1], SERVERPORT, &hints, &servinfo)) != 0) {
fprintf(stderr, "getaddrinfo: %s\n", gai_strerror(rv));
return 1;
}
// loop through all the results and make a socket
for(p = servinfo; p != NULL; p = p->ai_next) {
if ((sockfd = socket(p->ai_family, p->ai_socktype,
p->ai_protocol)) == -1) {
perror("talker: socket");
continue;
}
break;
}
if (p == NULL) {
fprintf(stderr, "talker: failed to bind socket\n");
return 2;
}
if ((numbytes = sendto(sockfd, argv[2], strlen(argv[2]), 0,
p->ai_addr, p->ai_addrlen)) == -1) {
perror("talker: sendto");
exit(1);
}
freeaddrinfo(servinfo);
printf("talker: sent %d bytes to %s\n", numbytes, argv[1]);
close(sockfd);
return 0;
}
You can, but for communication between two processes on the same host I'm sure there are better ways. I'm not a Windows guru unfortunately, but I'm sure there are some excellent local RPC frameworks you can use. UDP won't perform as well as a local socket solution, and you'll have to deal with (theoretically possible) packet loss etc. which is unnecessary.