Error "No such device" in call setsockopt when joining multicast group - c

I have a code in which send multicast datagrams.
A critical piece of code:
uint32_t port;
int sockfd, err_ip;
const uint32_t sizebuff = 65535 - (20 + 8);
unsigned char *buff = (unsigned char *) malloc(sizebuff);
struct sockaddr_in servaddr, cliaddr;
struct in_addr serv_in_addr;
struct ip_mreq req;
port = str2uint16(cmdsrv->ipport);
bzero(buff, (size_t)sizebuff);
bzero(&servaddr, sizeof(servaddr));
bzero(&serv_in_addr, sizeof(serv_in_addr));
err_ip = inet_aton(cmdsrv->ipaddr, &serv_in_addr);
if(( err_ip != 0 ) && ( port != 0 )) {
servaddr.sin_family = AF_INET;
servaddr.sin_addr = serv_in_addr;
servaddr.sin_port = htons(port);
memcpy(&req.imr_multiaddr,&serv_in_addr,sizeof(req.imr_multiaddr));
req.imr_interface.s_addr = INADDR_ANY;
sockfd = socket(AF_INET, SOCK_DGRAM, IPPROTO_UDP);
if( sockfd == -1 ) {
int outerror = errno;
char *retstr = "Couldn't open socket\n";
pthread_exit(retstr);
}
else {
struct in_addr ifaddr;
ifaddr.s_addr = INADDR_ANY;
int optres3 =
setsockopt( sockfd, IPPROTO_IP, IP_MULTICAST_IF, &ifaddr,
sizeof( ifaddr ));
if( optres3 == -1 ) {
int perrno = errno;
char *retstr = "Can't set IP_MULTICAST_IF for socket\n";
printf( "Error setsockopt: ERRNO = %s\n", strerror( perrno ));
printf( "%s",retstr );
pthread_exit(retstr);
}
unsigned char ttl = 32;
int optres2 =
setsockopt( sockfd, IPPROTO_IP, IP_MULTICAST_TTL, &ttl,
sizeof( ttl ));
if( optres2 == -1 ) {
int perrno = errno;
char *retstr = "Can't set IP_MULTICAST_TTL for socket\n";
printf("Error setsockopt: ERRNO = %s\n",strerror(perrno));
printf("%s",retstr);
pthread_exit(retstr);
}
int optres =
setsockopt( sockfd, IPPROTO_IP, IP_ADD_MEMBERSHIP, &req,
sizeof( req ));
if( optres == -1 ) {
int perrno = errno;
char *retstr = "Can't join to multicast-group\n";
printf("Error setsockopt: ERRNO = %s\n",strerror(perrno));
printf("%s",retstr);
pthread_exit(retstr);
}
// Bind port with socket
uint16_t cliport;
cliaddr.sin_family = AF_INET;
cliaddr.sin_addr.s_addr = INADDR_ANY;
if( strcmp( cmdsrv->ipport, "16011" ) == 0 ) {
cliport = str2uint16("16003");
cliaddr.sin_port = htons(cliport);
}
else if( strcmp( cmdsrv->ipport, "16012" ) == 0 ) {
cliport = str2uint16("16004");
cliaddr.sin_port = htons(cliport);
}
else {
printf("Device hasn't such port");
pthread_exit(NULL);
}
int bindres =
bind( sockfd, (struct sockaddr*)&cliaddr, sizeof( cliaddr ));
if( bindres == -1 ) {
int perrno = errno;
perror("Error in bind\n");
}
// ADD 1 BYTE
data rawdata;
rawdata.desc = 23;
printf( "SIZEOF = %d\n", sizeof( *( cmdsrv->cmd )));
memcpy( &rawdata.cmd, cmdsrv->cmd, sizeof( *( cmdsrv->cmd )));
printf( "RAWDATA: desc = %d, cmd = %d\n", rawdata.desc, rawdata.cmd );
int outerror = 0;
printf( "Send command to IP:\n addr = %s, port = %d\n",
inet_ntoa( servaddr.sin_addr ), ntohs( servaddr.sin_port ));
int size = sendto( sockfd, &rawdata, sizeof( rawdata ), 0,
(struct sockaddr*)&servaddr, sizeof( servaddr ));
if( size == -1 ) {
perror("Can't send command to socket");
}
...
Sometimes program executes successfully (at this moment I have IP - 192.168.80.122). I can capture my multicast datagram by wireshark. That's all OK.
But if I change my IP to 192.168.1.2, I get error when is called
int optres =
setsockopt( sockfd, IPPROTO_IP, IP_ADD_MEMBERSHIP, &req,
sizeof( req ));
And I can't even capture my multicast packet. Nothing is sent.
Where's bug?

If it works for one IP but not for another, maybe this can help.
What does "IP_ADD_MEMBERSHIP: No such device" mean?
It means that the tool is trying to use multicast but the network interface doesn't support it There are two likely causes:
Your machine doesn't have multicast support enabled. For example, on Linux and FreeBSD it is possible to compile a kernel which doesn't support multicast.
You don't have a route for multicast traffic. Some systems don't add this by default, and you need to run. route add -net 224.0.0.0 netmask 224.0.0.0 eth0 (or similar). If you wish to use RAT in unicast mode only, it is possible to add the multicast route on the loopback interface.

IP_ADD_MEMBERSHIP and bind() are only required for receiving multicast, use IP_MULTICAST_IF instead for effectively a "send-only membership" of a multicast group.
IP_MULTICAST_IF sets the kernel to send multicast packets for a given group on a given interface, it is effectively "send-only" as you will not be able to receive traffic on that group after setting. This varies by platform: Posix platforms generally function this way as an optimisation, whilst Win32 will perform software level routing to propagate locally generated packets.

You might not use the interface address as INADDR_ANY.
req.imr_interface.s_addr = INADDR_ANY;
check where the loopback is running using ifconfig.
lo Link encap:Local Loopback
inet addr:127.0.0.1 Mask:255.0.0.0
inet6 addr: ::1/128 Scope:Host
UP LOOPBACK RUNNING MTU:65536 Metric:1
You need to use interface address as inet addr i.e. 127.0.0.1
Check your loopback interface address and use that address only.

Related

Undertstanding UDP broadcast sending and receiving in C (system functions)

I'm trying to learn how sockets and networks work. For example in C in Linux. I have two simple programs. Both take ip and port as parameters. The first program is a server that broadcasts a message every second.
int main(int argc, char** argv){
struct sockaddr_in server;
if (argc < 3){ printf("\nToo few arguments. You need to pass ipv4 and port number!\n"); return 1; }
int port = -1;
if (isNumber(argv[2])) port = atoi(argv[2]);
if (port < 0){
printf("Error value for port!\n");
return 1;
}
/** prepare server */
server.sin_port = htons(port);
server.sin_family = AF_INET;
inet_aton(argv[1], &server.sin_addr);
int serverSocket = socket(AF_INET, SOCK_DGRAM, 0);
int broadcast=1;
setsockopt(serverSocket, SOL_SOCKET, SO_BROADCAST,
&broadcast, sizeof broadcast);
bind(serverSocket, (struct sockaddr*) &server, sizeof(server));
/** Client to send */
struct sockaddr_in client;
client.sin_port = htons(port);
client.sin_family = AF_INET;
client.sin_addr.s_addr = INADDR_BROADCAST;
char buf[128] = "Test from server";
while(1){
sleep(1);
sendto(serverSocket, buf, 18, 0, (struct sockaddr*) &client, sizeof(client));
}
close(serverSocket);
return 0;
}
The second program is a simple client that receives a message, prints it out, and outputs the sender's ip.
int main(int argc, char** argv){
struct sockaddr_in currUser;
if (argc < 3){ printf("\nToo few arguments. You need to pass ipv4 and port number!\n"); return 1; }
int port = -1;
if (isNumber(argv[2])) port = atoi(argv[2]);
if (port < 0){
printf("Error value for port!\n");
return 1;
}
currUser.sin_port = htons(port);
currUser.sin_family = AF_INET;
inet_aton(argv[1], &currUser.sin_addr);
int userSocket = socket(AF_INET, SOCK_DGRAM, 0);
bind(userSocket, (struct sockaddr*) &currUser, sizeof(currUser));
/** listen */
char buf[128];
struct sockaddr_in brd;
unsigned slen = sizeof(brd);
while(1){
int readCount = recvfrom(userSocket, buf, 128, 0, (struct sockaddr *)&brd, &slen);
buf[readCount] = 0;
printf("Get %s\n", buf);
printf("Ip who send: %s\n", inet_ntoa(brd.sin_addr));
}
close(userSocket);
return 0;
}
I expect that recvfrom get the source address of the message in brd . If I send directly to the client from the server (i.e. not broadcast, but in the client parameter for sendto specifying directly ip ), it works. However, for the broadcast case, the address is different. Here is an example:
The output for $route is as follows:
Destination Gateway Genmask Flags Metric Ref Use Iface
default _gateway 0.0.0.0 UG 600 0 0 wlp3s0
link-local 0.0.0.0 255.255.0.0 U 1000 0 0 br-29e12aa6bbb8
172.17.0.0 0.0.0.0 255.255.0.0 U 0 0 0 docker0
172.18.0.0 0.0.0.0 255.255.0.0 U 0 0 0 br-29e12aa6bbb8
192.168.0.0 0.0.0.0 255.255.255.0 U 600 0 0 wlp3s0
Tell me please, I don't understand something in the operation of the recvfrom function or how the packet is transmitted over the network within these two programs?

Socket Programming: UDP Client-Server in C

I'm trying to write a client server program using UDP, and wait-and-stop, but I haven't got to that part, I'm still trying to figure it out how the two processes (server and client) communicate, because on my client program, the user needs to enter the server name or IP address, and a port name, and then send an expression that the server should calculate. However, I dug some tutorials in the internet and after coding accordingly (or I thought so) I can't make the client communicate with the server. Below is my code, please enlighten me what I'm doing wrong, if it's the bind(), sendto(), recvfrom() or socket(), or all of them. I can't see what exactly is wrong. I know that the client-side shouldn't run on a infinite loop, but so far I want to make the programs communicate with each other, afterwards I'll polish my code. Thanks!
client-side code:
#include <stdio.h> // Default System Calls
#include <stdlib.h> // Needed for OS X
#include <string.h> // Needed for Strlen
#include <sys/socket.h> // Needed for socket creating and binding
#include <netinet/in.h> // Needed to use struct sockaddr_in
#include <time.h> // To control the timeout mechanism
#define EXPR_SIZE 1024
#define BUFLEN 512
#define TRUE 1
#define FALSE 0
#define SERVERLEN 1024
int main(int argc, char **argv){
long portNum; // Since it's possible to input a value bigger
// than 65535 we'll be using long to
// avoid overflows
char expr[EXPR_SIZE];
char server[SERVERLEN];
int fd; // file descriptor for the connected socket
int buf[512];
struct hostent *h; // information of the host
unsigned int addrLen; // address length after getting the port number
struct sockaddr_in myaddr; // address of the client
struct sockaddr_in servaddr; // server's address
unsigned int exprLen;
socklen_t slen = sizeof(servaddr);
printf("Enter server name or IP address:");
scanf("%s",server);
printf("Enter port:");
scanf("%ld",&portNum);
if ((portNum < 0) || (portNum > 65535)) {
printf("Invalid port number. Terminating.");
return 0;
}
printf("Enter expression:");
scanf("%s",expr);
if((fd = socket(AF_INET, SOCK_DGRAM, 0)) < 0){
perror("cannot create socket");
return 0;
}
memset((char *)&myaddr, 0, sizeof(myaddr));
myaddr.sin_family = AF_INET;
myaddr.sin_addr.s_addr = htonl(INADDR_ANY);
myaddr.sin_port = htons(0);
if(bind(fd, (struct sockaddr *)&myaddr, sizeof(myaddr)) < 0){
perror("cannot bind");
return 0;
}
/*
// Discovering the port number the OS allocated
addrLen = sizeof(myaddr);
if(getsockname(fd, (struct sockaddr *)&myaddr, &addrLen) < 0){
perror("cannot getsockname");
return 0;
}
printf("local port number = %d\n", ntohs(myaddr.sin_port));
*/
memset((char*)&servaddr, 0, sizeof(servaddr));
servaddr.sin_family = AF_INET;
servaddr.sin_port = htonl(portNum);
exprLen = sizeof(expr);
while(TRUE){
printf("Sending message to %s port %ld\n",server, portNum);
if (sendto(fd, expr, strlen(expr), 0, (struct sockaddr *)&servaddr, slen) < 0) {
perror("cannot sendto()");
}
printf("Success\n");
}
return 0;
}
Server-side code:
#include <stdio.h> // Default System Calls
#include <stdlib.h> // Needed for OS X
#include <string.h> // Needed for Strlen
#include <sys/socket.h> // Needed for socket creating and binding
#include <netinet/in.h> // Needed to use struct sockaddr_in
#include <time.h> // To control the timeout mechanism
#define EXPR_SIZE 1024
#define BUFLEN 512
#define TRUE 1
#define SERVERLEN 1024
int main(int argc, char **argv){
struct sockaddr_in myaddr; // address of the server
struct sockaddr_in claddr; // address of the client
char buf[BUFLEN];
int fd;
long recvlen;
socklen_t clientlen;
if((fd = socket(AF_INET, SOCK_DGRAM, 0)) < 0){
perror("cannot create socket");
return 0;
}
memset((char *)&myaddr, 0, sizeof(myaddr));
myaddr.sin_family = AF_INET;
myaddr.sin_addr.s_addr = htonl(INADDR_ANY);
myaddr.sin_port = htons(0);
if(bind(fd, (struct sockaddr *)&myaddr, sizeof(myaddr)) < 0){
perror("cannot bind");
return 0;
}
clientlen = sizeof(claddr);
while (TRUE) {
recvlen = recvfrom(fd, buf, BUFLEN, 0, (struct sockaddr *)&claddr, &clientlen);
if (recvlen < 0) {
perror("cannot recvfrom()");
return 0;
}
printf("Received %ld bytes\n",recvlen);
buf[recvlen] = 0;
printf("Received message: \"%s\"\n",buf);
}
return 0;
}
The server program doesn't output anything, while the client outputs until the process is interrupted:
Enter server name or IP address:127.0.0.1
Enter port:30
Enter expression:2+2
Sending message to 127.0.0.1 port 30
cannot sendto(): Can't assign requested address
I tried changing the server name to localhost, and other ports, but to no avail.
When developing networking software (especially when using the BSD socket interface), it's important to keep things as simple as possible until you've established basic communication. Then you can incrementally add functionality, while making sure that you don't break anything along the way.
On the client side, keeping things simple means
Don't call bind in the client. The OS will choose an appropriate interface and assign a random port number, so there's no need to bind the socket.
Use a hard-coded server address (e.g. 127.0.0.1). Address 127.0.0.1 (0x7f000001) is the local host address, suitable for sending packets to a server on the same machine.
Use a hard-coded port number (e.g. 50037). Ephemeral port numbers should be greater than 0xC000 hex (49152 decimal).
Use a hard-coded message, e.g. "hello".
With that in mind, here's what the client software looks like
int main( void )
{
int fd;
if ( (fd = socket(AF_INET, SOCK_DGRAM, 0)) < 0 ) {
perror("socket failed");
return 1;
}
struct sockaddr_in serveraddr;
memset( &serveraddr, 0, sizeof(serveraddr) );
serveraddr.sin_family = AF_INET;
serveraddr.sin_port = htons( 50037 );
serveraddr.sin_addr.s_addr = htonl( 0x7f000001 );
for ( int i = 0; i < 4; i++ ) {
if (sendto( fd, "hello", 5, 0, (struct sockaddr *)&serveraddr, sizeof(serveraddr)) < 0 ) {
perror( "sendto failed" );
break;
}
printf( "message sent\n" );
}
close( fd );
}
On the server side, keeping things simple means
Bind to INADDR_ANY, i.e. let the OS pick an appropriate interface.
Bind to a hard-coded port, e.g. 50037 (must be the same port the client uses).
Don't request the address information from recvfrom, i.e. pass NULL, 0 as the last two parameters.
With that in mind, here's what the server software looks like
int main( void )
{
int fd;
if ( (fd = socket(AF_INET, SOCK_DGRAM, 0)) < 0 ) {
perror( "socket failed" );
return 1;
}
struct sockaddr_in serveraddr;
memset( &serveraddr, 0, sizeof(serveraddr) );
serveraddr.sin_family = AF_INET;
serveraddr.sin_port = htons( 50037 );
serveraddr.sin_addr.s_addr = htonl( INADDR_ANY );
if ( bind(fd, (struct sockaddr *)&serveraddr, sizeof(serveraddr)) < 0 ) {
perror( "bind failed" );
return 1;
}
char buffer[200];
for ( int i = 0; i < 4; i++ ) {
int length = recvfrom( fd, buffer, sizeof(buffer) - 1, 0, NULL, 0 );
if ( length < 0 ) {
perror( "recvfrom failed" );
break;
}
buffer[length] = '\0';
printf( "%d bytes: '%s'\n", length, buffer );
}
close( fd );
}

Need IPv6 Multicast C code that works on iOS 9

Apple now requires iOS 9 apps to be IPv6 compliant. We're mostly OK, except for a bit of code which sends a UDP broadcast - this now fails in iOS 9.
Everything I read tells me that UDP multicast is the right way to do this in IPv6. I've found some example code, but it doesn't work on any version of iOS or Mac OS X I've tried.
This code is being called from a C/C++ lib inside our program - difficult to make a callback into Swift, Obj-C, Java, etc. And this code will be shared by a Mac OS X and Android version of our app. One would think it's possible to do IPv6 multicast in C in any POSIX environment!
In the sample below, execution succeeds up to the final sendto() call, which actually sends the UDP message. That sendto() fails, with errno set to EBROKENPIPE (22) after the failure.
My best guess is that I'm missing some required setsockopt() call, or am using the wrong multicast address. Right now, I'm stumped.
Here's the function call I'm making (to multicast "Is anybody out there?" on UDP port 4031):
char *msg = "Is anybody out there?";
err = multicast_udp_msg ( "FF01::1111", 4031, msg, strlen(msg) );
Here's the code that is being called:
// Multicasts a message on a specific UDP port.
// myhost - IPv6 address on which to multicast the message (i.e., ourself)
// port - UDP port on which to broadcast the mssage
// msg - message contents to broadcast
// msgsize - length of message in bytes
// Return value is zero if successful, or nonzero on error.
int multicast_udp_msg ( char *myhost, short port, char *msg, size_t msgsize )
{
int sockfd, n;
char service[16] = { 0 };
int err = 0;
struct addrinfo hints = { 0 }, *res, *ressave;
struct sockaddr_storage addr = { 0 };
hints.ai_family = AF_INET6;
hints.ai_socktype = SOCK_DGRAM;
sprintf ( service, "%hd", port );
n = getaddrinfo ( myhost, service, &hints, &res );
if ( n < 0 )
{
fprintf(stderr, "getaddrinfo error:: [%s]\n", gai_strerror(n));
return -1;
}
ressave = res;
sockfd = socket ( res->ai_family, res->ai_socktype, res->ai_protocol );
if ( sockfd >= 0 )
{
memcpy ( &addr, res->ai_addr, sizeof ( addr ) );
if ( joinGroup ( sockfd, 0, 8, &addr ) == 0 )
if ( bind ( sockfd, res->ai_addr, res->ai_addrlen ) == 0 )
if ( sendto ( sockfd, msg, msgsize, 0, (struct sockaddr *) &addr, sizeof ( addr ) ) < 0 )
err = errno;
close ( sockfd );
res = res->ai_next;
}
freeaddrinfo ( ressave );
return err;
}
int
joinGroup(int sockfd, int loopBack, int mcastTTL,
struct sockaddr_storage *addr)
{
int r1, r2, r3, retval;
retval=-1;
switch (addr->ss_family) {
case AF_INET: {
struct ip_mreq mreq;
mreq.imr_multiaddr.s_addr=
((struct sockaddr_in *)addr)->sin_addr.s_addr;
mreq.imr_interface.s_addr= INADDR_ANY;
r1= setsockopt(sockfd, IPPROTO_IP, IP_MULTICAST_LOOP,
&loopBack, sizeof(loopBack));
if (r1<0)
perror("joinGroup:: IP_MULTICAST_LOOP:: ");
r2= setsockopt(sockfd, IPPROTO_IP, IP_MULTICAST_TTL,
&mcastTTL, sizeof(mcastTTL));
if (r2<0)
perror("joinGroup:: IP_MULTICAST_TTL:: ");
r3= setsockopt(sockfd, IPPROTO_IP, IP_ADD_MEMBERSHIP,
(const void *)&mreq, sizeof(mreq));
if (r3<0)
perror("joinGroup:: IP_ADD_MEMBERSHIP:: ");
} break;
case AF_INET6: {
struct ipv6_mreq mreq6;
memcpy(&mreq6.ipv6mr_multiaddr,
&(((struct sockaddr_in6 *)addr)->sin6_addr),
sizeof(struct in6_addr));
mreq6.ipv6mr_interface= 0; // cualquier interfaz
r1= setsockopt(sockfd, IPPROTO_IPV6, IPV6_MULTICAST_LOOP,
&loopBack, sizeof(loopBack));
if (r1<0)
perror("joinGroup:: IPV6_MULTICAST_LOOP:: ");
r2= setsockopt(sockfd, IPPROTO_IPV6, IPV6_MULTICAST_HOPS,
&mcastTTL, sizeof(mcastTTL));
if (r2<0)
perror("joinGroup:: IPV6_MULTICAST_HOPS:: ");
r3= setsockopt(sockfd, IPPROTO_IPV6,
IPV6_JOIN_GROUP, &mreq6, sizeof(mreq6));
if (r3<0)
perror("joinGroup:: IPV6_ADD_MEMBERSHIP:: ");
} break;
default:
r1=r2=r3=-1;
}
if ((r1>=0) && (r2>=0) && (r3>=0))
retval=0;
return retval;
}
Thoughts welcome!
-Tim
After some back-and-forth with Apple, and some additional context, we have an answer. But it's not the answer to my original question. First, here's the Apple thread for context:
https://forums.developer.apple.com/message/71107
It turns out that IPv6 multicast was not actually what we needed to solve the real problem at hand - namely, finding a legacy embedded device on a local Wi-Fi network. We really had to use IPv4 UDP broadcast to do that. Our embedded device ignores IPv6 multicast packets like the Earth ignores neutrinos flying through it.
Apple gave us a setsockopt() call which enabled IPv4 UDP broadcast to work in iOS 9 on an infrastructure Wi-Fi network. That is the intended use case for this feature. And Apple also gave us a likely cause of failure when that broadcast failed to work in an Ad Hoc Wi-Fi network (that appears to be a known iOS 9 issue).
So, although my original question is not answered here, the underlying issue has been resolved.

How to get the name of the client when receiving an HTTP request?

I'm writing a basic proxy server in C.
I want to identify the server/machine I am receiving the request from, by name or IP.
How does one do this? I'm not sure where to get the information from.
Here's my connection code:
unsigned short port = atoi(argv[1]); /* port number to listen on */
struct sockaddr_in server;
server.sin_family = PF_INET;
server.sin_addr.s_addr = INADDR_ANY;
server.sin_port = htons( port );
/* host-to-network-short() convert to big endian */
int len = sizeof( server );
if ( bind( sock, (struct sockaddr *)&server, len ) < 0 )
{
perror( "bind() failed" );
return EXIT_FAILURE;
}
/* activate the socket as a listener */
listen( sock, 5 ); /* 5 is number of backlogged waiting client requests */
//printf( "Listener socket created and bound to port %d on fd %d\n", port, sock );
struct sockaddr_in client;
while ( 1 )
{
// printf( "Blocked on accept()\n" );
unsigned int fromlen;
int newsock = accept( sock, (struct sockaddr *)&client, &fromlen );
/* accept() blocks */
//printf( "Accepted client connection\n" );
char buffer[5000];
int n = read( newsock, buffer, 4999 );
if ( n < 1 )
{
perror("Read() failed.\n");
}
else
{
buffer[n] = '\0';
//printf( "Rcvd message from client: \n\n----\n\n%s\n\n----\n\n", buffer );
}
Here is how you retrieve IP & hostname:
struct sockaddr_in client;
[...]
int newsock = accept( sock, (struct sockaddr *)&client, &fromlen );
printf("Client accepted: %s \n", inet_ntoa(client.sin_addr));
// And the host name
struct hostent *hostName;
struct in_addr ipv4addr;
inet_pton(AF_INET, inet_ntoa(client.sin_addr), &ipv4addr);
hostName = gethostbyaddr(&ipv4addr, sizeof ipv4addr, AF_INET);
printf("Host name: %s\n", hostName->h_name);

gethostbyname, connecting to the internet at large?

I'm writing a basic proxy server in C for class.
I'm testing with firefox, and I've got the server successfully receiving the browser's requests.
But now I need to send them out to the internet to get the pages the browser wants, and I'm hesitant.
Here is my present code for connecting.
I'm not sure if port 8080 is correct, and I'm not sure what to put for "gethostbyname".
That's the portion I was hoping to get some advice on.
int sock = socket( PF_INET, SOCK_STREAM, 0 );
if ( sock < 0 )
{
perror( "socket() failed" );
return EXIT_FAILURE;
}
struct sockaddr_in server;
struct hostent * hp;
server.sin_family = PF_INET;
hp = gethostbyname( "localhost" );
if ( hp == NULL )
{
perror( "Unknown host" );
return EXIT_FAILURE;
}
bcopy( (char *)hp->h_addr, (char *)&server.sin_addr, hp->h_length );
int port = 8080;
server.sin_port = htons( port );
if ( connect( sock, (struct sockaddr *)&server, sizeof( server ) ) < 0 )
{
perror( "connect() failed" );
return EXIT_FAILURE;
}
That entire gethostbyname, copying around (ha - even with the overly old bcopy)... just use getaddrinfo (extensive error checking left out for brevity):
int ret = getaddrinfo("localhost", "80" /* (or 8080, whichever applies) */, NULL, &res);
if (ret == 0) {
const struct addrinfo *r;
for (r = res; r != NULL || ret != 0; r = r->ai_next)
ret = connect(fd, res->ai_addr, res->ai_addrlen);
}
freeaddrinfo(res);

Resources