I'm trying to write a simple program which uses bind. The code compiles on solaris, but I get a bind() failed with Invalid Argument error.
I have tried many times but getting the same error, I'm unable to figure out the error.
Here is the code :
int my_func ()
{
struct sockaddr_storage name;
struct addrinfo hints, *res;
int status;
char hostnamestr[256];
gethostname (hostnamestr, 256);
int iRC;
memset(&hints, 0, sizeof(hints));
hints.ai_family = AF_UNSPEC;
hints.ai_socktype = SOCK_STREAM;
if ((status = getaddrinfo(hostnamestr, NULL, &hints, &res) != 0))
{
printf("getaddrinfo: %s\n", gai_strerror(status));
return 1;
}
memcpy(&name, res->ai_addr, res->ai_addrlen);
freeaddrinfo(res);
monsocket = socket (name.ss_family, SOCK_STREAM, IPPROTO_TCP);
int iLastError = WSAGetLastError ();
if (monsocket == -1)
{
fprintf (stderr, "cannot open socket for monitors [%s]\n", wsaerror (iLastError));
return 1;
}
sockopts(monsocket);
int flags;
flags = fcntl (monsocket, F_GETFL);
iLastError = WSAGetLastError ();
if (flags < 0)
{
fprintf (stderr, "cannot get flags for socket [%s]\n", wsaerror (iLastError));
return 1;
}
iRC = fcntl (monsocket, F_SETFL, flags | O_NONBLOCK);
iLastError = WSAGetLastError ();
if (iRC == -1)
{
fprintf (stderr, "cannot set flags for socket [%s]\n", wsaerror (iLastError));
return 1;
}
int iPort;
if(name.ss_family == AF_INET)
{
((struct sockaddr_in *) &name)->sin_port = htons (8091);
}
else if(name.ss_family == AF_INET6)
{
((struct sockaddr_in6 *) &name)->sin6_port = htons (8091);
}
struct sockaddr_in* ipv = (struct sockaddr_in *) &name;
printf("connecting to addr: %s\n", inet_ntoa(ipv->sin_addr));
iRC = bind (monsocket, (struct sockaddr *) &name, sizeof (name));
iLastError = WSAGetLastError ();
if (iRC == -1)
{
close(monsocket);
monsocket=-1;
fprintf (stderr, "could not bind to port %d\n", iPort);
printf("Error %s",wsaerror (iLastError));
return 1;
}
else
{
fprintf (SCHED_SHOW_MSG, "bound on port %i\n", ntohs (iPort));
}
iRC = listen (monsocket, SOMAXCONN);
iLastError = WSAGetLastError ();
if (iRC == -1)
{
fprintf (stderr, "could not listen to socket [%s]\n", wsaerror (iLastError));
return 1;
}
return 0;
}
bind (monsocket, (struct sockaddr *) &name, sizeof (name))
Your sizeof(name) yields the size of the generic sockaddr_storage size. You need the size of sockaddr_in or sockaddr_in6.
In any case, you'd be better of by just using the stuff from getaddrinfo directly:
monsocket = socket(res->ai_family, res->ai_socktype, res->ai_protocol);
bind(monsocket, res->ai_addr, res->ai_addrlen);
In order to do that you'll have to move your freeaddrinfo(res) call.
i got same error. and later found that i created socket for AF_INET and was trying to bind using IPv6 address.
Related
I have tried below code in multiple iOS, MacOS.
This is server code
void *run_server(void *thread_id) {
int server_fd, new_socket;
struct sockaddr_in server, client;
int opt = 1;
int addrlen = sizeof(server);
// Creating socket file descriptor
if ((server_fd = socket(AF_INET, SOCK_STREAM, 0)) == 0) {
perror("socket");
return NULL;
}
// Forcefully attaching socket to the port
if (setsockopt(server_fd, SOL_SOCKET, SO_REUSEADDR, &opt, sizeof(opt))) {
perror("setsockopt");
return NULL;
}
server.sin_family = AF_INET;
server.sin_addr.s_addr = ip("10.10.10.20"); // bind IP
server.sin_port = htons(27042);
// Forcefully attaching socket to the port
if (bind(server_fd, (struct sockaddr *)&server, sizeof(server)) < 0) {
perror("bind");
return NULL;
}
if (listen(server_fd, 3) < 0) {
perror("listen");
return NULL;
}
printf("Server is running with %u:%d\n", server.sin_addr.s_addr, htons(server.sin_port));
while (1) {
if ((new_socket = accept(server_fd, (struct sockaddr *)&client, (socklen_t*)&addrlen))<0) {
perror("accept");
return NULL;
}
printf("Client connected with %u:%d\n", client.sin_addr.s_addr, client.sin_port);
}
}
This is client code
void scan(unsigned int ip, int port) {
int sock = 0;
struct sockaddr_in serv_addr;
if ((sock = socket(AF_INET, SOCK_STREAM, 0)) < 0) {
printf("\nSocket creation error\n");
return;
}
serv_addr.sin_family = AF_INET;
serv_addr.sin_port = htons(port);
serv_addr.sin_addr.s_addr = ip;
printf("IP %u, port %d\n", ip, port);
int connected = connect(sock, (struct sockaddr *)&serv_addr, sizeof(serv_addr));
if (connected != 0) {
char errorMsg[256];
strerror_r(errno, errorMsg, 256);
printf("Error %s\n", errorMsg);
}
if (connected < 0) {
close(sock);
return;
}
}
void *run_scan(void *thread_id) {
while (1) {
scan(ip("10.10.10.20"), 27042);
usleep(1000000);
}
return NULL;
}
And the main function
int main(int argc, const char * argv[]) {
pthread_t thread1;
if (pthread_create(&thread1, NULL, run_server, (void *)1)) {
printf("Can't create thread run_server");
}
pthread_t thread2;
if (pthread_create(&thread2, NULL, run_scan, (void *)2)) {
printf("Can't create thread run_scan");
}
while (1) sleep(1);
return 0;
}
Problem description:
This code is working normally with local IP (DHCP assigned IP). However when I connect to VPN and bind server IP to PPP network interface IP which is 10.10.10.20 (as above example code). I could not be able to open connect to that IP. The error is "Connection timeout". Note, the other host can still be able to connect to the server with IP 10.10.10.20.
Appreciate if any knowledge sharing regarding this situation.
Found the answer, basically this is a restriction imposed by the Linux kernel.
More info: https://www.softether.org/4-docs/1-manual/B._Troubleshooting_and_Supplemental/11.1_Troubleshooting
TCPServer
#include<stdio.h>
#include<sys/types.h>
#include<sys/socket.h>
#include<netinet/ip.h>
#include<netinet/in.h>
#include<string.h>
#include<stdlib.h>
int main()
{
int fd = socket(AF_INET, SOCK_STREAM, 0);
if(fd == -1)
{
printf("socket failed!\n");
exit(0);
}
printf("Enter port: ");
int port;
scanf("%d",&port);
struct sockaddr_in server;
server.sin_family = AF_INET;
server.sin_port = htons(port);
server.sin_addr.s_addr = INADDR_ANY;
int bind_ret = bind(fd, (struct sockaddr*)(&server), sizeof(server));
if(bind_ret == -1)
{
printf("bind failed!\n");
exit(0);
}
int listen_ret = listen(fd, 10);
if(listen_ret == -1)
{
printf("listen failed!\n");
exit(0);
}
struct sockaddr_in client;
int l = sizeof(client);
int client_fd = accept(fd, (struct sockaddr*)(&client), &l);
if(client_fd == -1)
{
printf("accept failed!\n");
exit(0);
}
while(1)
{
char msg_recv[50];
int recv_ret = recv(client_fd, msg_recv, sizeof(msg_recv),0);
if(recv_ret == -1)
{
printf("recv failed!\n");
exit(0);
}
msg_recv[recv_ret]='\0';
if(strcmp("bye",msg_recv)==0)
{
exit(0);
}
printf("Message recieved: %s\n",msg_recv);
char msg_send[50];
printf("Enter message: ");
scanf(" %s",msg_send);
int send_ret = send(client_fd, msg_send, strlen(msg_send),0);
if(send_ret == 0)
{
printf("send failed!\n");
}
if(strcmp("bye",msg_send) == 0)
exit(0);
}
}
TCPClient
#include<stdio.h>
#include<sys/socket.h>
#include<sys/types.h>
#include<netinet/ip.h>
#include<netinet/in.h>
#include<string.h>
#include<stdlib.h>
int main()
{ int fd = socket(AF_INET, SOCK_STREAM, 0);
if(fd == -1)
{
printf("socket failed!\n");
exit(0);
}
int port;
printf("Enter port number: ");
scanf("%d",&port);
struct sockaddr_in client;
client.sin_family = AF_INET;
client.sin_port = htons(port);
client.sin_addr.s_addr = INADDR_ANY;
int connect_ret = connect(fd, (struct sockaddr*)(&client), sizeof(client));
if(connect_ret == -1)
{
printf("connect failed!\n");
exit(0);
}
while(1)
{
printf("Enter message: ");
char msg_send[50];
scanf("%s",msg_send);
int send_ret = send(fd, msg_send, strlen(msg_send), 0);
if(send_ret == -1)
{
printf("send failed!\n");
exit(0);
}
if(strcmp("bye", msg_send)==0)
{
exit(0);
}
char msg_recv[50];
int recv_ret = recv(fd, msg_recv, sizeof(msg_recv), 0);
if(recv_ret == -1)
{
printf("recv failed!\n");
exit(0);
}
msg_recv[recv_ret]= '\0';
if(strcmp("bye", msg_recv) == 0)
exit(0);
printf("Message recieved: %s \n",msg_recv);
}
}
In the above program for Server, recv and send were called by passing client_fd as the argument, while in the program for Client, recv and send were called by passing fd as the argument. I wanted to know why on the server side we did not use its own socket file descriptor like we did on the client side?
The server’s fd descriptor is a listen()’ing socket. It can’t perform any I/O, only receive incoming client connections. accept() pulls a pending client connection from fd’s queue and returns a new socket descriptor that can perform I/O with that client.
The client’s fd descriptor is a connect()‘ing socket. It can perform I/O with the server once its connection has been accepted.
This is the code snippet (from beejus) where I am trying to create a process which will create a thread which will act as a Unix Domain Socket Server.
void *domain_socket_cepki_server() {
s = socket(AF_UNIX, SOCK_STREAM, 0);
fprintf(stderr, "socket val is : %d\n", s);
if (s == -1) {
perror("socket");
fprintf(stderr, "SOCKET ERROR: %d\n", s);
}
memset(&local, 0, sizeof(struct sockaddr_un));
local.sun_family = AF_UNIX;
strcpy(local.sun_path, SOCK_PATH);
unlink(local.sun_path);
//len = strlen(local.sun_path) + sizeof(local.sun_family);
rc = bind(s, (struct sockaddr *) &local, sizeof(local));
if (rc == -1) {
perror("bind");
fprintf(stderr, "bind failed %d : %s", errno, strerror(errno));
exit(1);
}
if (listen(s, 5) == -1) {
perror("listen");
fprintf(stderr, "listen failed : %s", strerror(errno));
exit(1);
}
int done, n;
printf("Waiting for a connection...\n");
t = sizeof(remote);
if ((s2 = accept(s, (struct sockaddr *)&remote, &t)) == -1) {
perror("accept");
exit(1);
}
// send and recv code further.
}
With this I am getting following error:
bind: Invalid argument
bind() EINVAL says the following:
EINVAL The socket is already bound to an address.
EINVAL addrlen is wrong, or addr is not a valid address for this
socket's domain.
What can go wrong in this bind() system call ?
Hello I made this program based on the msdn winsock2.h tutorial.I have server program and a client one.Everything works fine, I even made one sided chat from the server to the client, more like broadcast.Now i want to see the client's IP address when he connects.I think i did it right but, on every connect it shows different address in strange form like 12.2.90.0 then, 12.2.46.0.
This is the server code :
#include <cstdlib>
#include <iostream>
#include <winsock2.h>
#include <ws2tcpip.h>
#include <stdio.h>
#include <iphlpapi.h>
#define DEFAULT_PORT "27015"
using namespace std;
int main(int argc, char *argv[])
{
WSADATA wsaData;
int iResult;
SOCKET ListenSocket = INVALID_SOCKET;
SOCKET ClientSocket = INVALID_SOCKET;
struct sockaddr_in client_info;
char * addr;
struct addrinfo *result = NULL;
struct addrinfo hints;
int iSendResult;
char buffer[50];
char typebuffer[50];
char connected_ip[15]= "\0";
int port;
// Initialize Winsock
iResult = WSAStartup(MAKEWORD(2,2), &wsaData);
if (iResult != 0) {
printf("WSAStartup failed with error: %d\n", iResult);
return 1;
} cout<<"Winsock initialized..."<<endl;
ZeroMemory(&hints, sizeof(hints));
hints.ai_family = AF_INET;
hints.ai_socktype = SOCK_STREAM;
hints.ai_protocol = IPPROTO_TCP;
hints.ai_flags = AI_PASSIVE;
// Resolve the server address and port
iResult = getaddrinfo(NULL, DEFAULT_PORT, &hints, &result);
if ( iResult != 0 ) {
printf("getaddrinfo failed with error: %d\n", iResult);
WSACleanup();
return 1;
}
// Create a SOCKET for connecting to server
ListenSocket = socket(result->ai_family, result->ai_socktype, result->ai_protocol);
if (ListenSocket == INVALID_SOCKET) {
printf("socket failed with error: %ld\n", WSAGetLastError());
freeaddrinfo(result);
WSACleanup();
return 1;
}
// Setup the TCP listening socket
iResult = bind( ListenSocket, result->ai_addr, (int)result->ai_addrlen);
if (iResult == SOCKET_ERROR) {
printf("bind failed with error: %d\n", WSAGetLastError());
freeaddrinfo(result);
closesocket(ListenSocket);
WSACleanup();
return 1;
} else cout<<"Listening socket initialized...\nAccepting connections now..."<<endl;
freeaddrinfo(result);
iResult = listen(ListenSocket, SOMAXCONN);
if (iResult == SOCKET_ERROR) {
printf("listen failed with error: %d\n", WSAGetLastError());
closesocket(ListenSocket);
WSACleanup();
return 1;
}
// Accept a client socket
ClientSocket = accept(ListenSocket, (struct sockaddr*)&client_info, NULL);
if (ClientSocket == INVALID_SOCKET) {
printf("accept failed with error: %d\n", WSAGetLastError());
closesocket(ListenSocket);
WSACleanup();
return 1;
} else
// converting the address in readable form
addr = inet_ntoa(client_info.sin_addr);
printf("Client connected, IP address is: %s\n", addr );
{
}
closesocket(ListenSocket);
for(;;)
{
cin.getline(typebuffer,50);
strcpy(buffer,"SERVER: ");
strcat(buffer,typebuffer);
send( ClientSocket, buffer, 50, 0 );
*buffer = '\0';
}
system("PAUSE");
return EXIT_SUCCESS;
}
You are providing a sockaddr_in struct to accept(), but you are not telling it how large the struct is. You are not zeroing out the sockaddr_in, and accept() is not filling it in, so you end up with random results when calling inet_ntoa(). This behavior is documented:
accept function
If addr and/or addrlen are equal to NULL, then no information about the remote address of the accepted socket is returned.
The addrlen parameter cannot be NULL if the addr parameter is not NULL:
int addrlen = sizeof(client_info); // <-- Add this
ClientSocket = accept(ListenSocket, (struct sockaddr*)&client_info, &addrlen);
I'm trying to establish UDP communication between a MAC OS and an iPod through Wi-Fi, at this point I'm able to send packets from the iPod and I can see those packets have the right MAC and ip addresses (I'm using wireshark to monitor the network) but the MAC receives the packets only when the wireshark is on, otherwise recvfrom() returns -1.
When I try to transmit from MAC to iPhone I have the same result, I can see the packets are sent but the iPhone doesn't seem to get them.
I'm using the next code to send:
struct addrinfo hints;
int rv;
memset(&hints, 0, sizeof hints);
hints.ai_family = AF_UNSPEC;
hints.ai_socktype = SOCK_DGRAM;
if ((rv = getaddrinfo(IP, 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;
}
while (cond)
sntBytes += sendto(sockfd, message, strlen(message), 0, p->ai_addr, p->ai_addrlen);
return 0;
and this code to receive:
struct addrinfo hints, *p;
int rv;
memset(&hints, 0, sizeof hints);
hints.ai_family = AF_UNSPEC; // set
hints.ai_socktype = SOCK_DGRAM;
hints.ai_flags = AI_PASSIVE; // use to AF_INET to force IPv4 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;
}
addr_len = sizeof their_addr;
fcntl(sockfd, F_SETFL,O_NONBLOCK);
int rcvbuf_size = 128 * 1024; // That's 128Kb of buffer space.
setsockopt(sockfd, SOL_SOCKET, SO_RCVBUF,
&rcvbuf_size, sizeof(rcvbuf_size));
printf("listener: waiting to recvfrom...\n");
while (cond)
rcvBytes = recvfrom(sockfd, buf, MAXBUFLEN-1 , 0, (struct sockaddr *)&their_addr, &addr_len);
return 0;
What am I missing?
It would be good to get some more information about the length of data you are sending.
I will assume you are trying to send an ASCII string.
Also, this appears to be either never called or an infinite send loop:
while (cond)
sntBytes += sendto(sockfd, message, strlen(message), 0, p->ai_addr, p->ai_addrlen);
You might want to use code that actually includes some error checking:
Send String
int sendResult = send( connectedSocket, stringBuffer, stringLength, 0 );
if (sendResult == -1) {
perror("Error while trying to send string!");
}
else {
NSLog(#"String '%s' sent successfully", stringBuffer );
}
Receive String
memset( ReceiveBuffer, '\0', sizeof(ReceiveBuffer) );
int receiveResult = recv( connectedSocket, ReceiveBuffer, sizeof(ReceiveBuffer), 0);
if ( receiveResult == -1 ) {
perror("recv");
}
else {
NSLog(#"String received successfully: '%s'", ReceiveBuffer );
}