Celebrate National IT Professionals Day with 3 months of free Premium Membership. Use Code ITDAY17

x
?
Solved

c++ connect() permission denied, why?

Posted on 2009-05-06
17
Medium Priority
?
983 Views
Last Modified: 2012-08-14
Hi all,

I have a c++ client that communicates with a service on a small network. I am trying to let the user find the IP address of the service by sending a message to a broadcast IP address, to which my service will respond, etc. I don't think I am doing this correctly, however...

The IP of the service is 192.168.1.102
The subnet mask is 255.255.255.0

As far as I could tell, the corresponding broadcast would be 192.168.1.255, is that right? Well, when I try to connect() to that IP address, it always comes back with errno 13 Permission denied. Does anyone have any idea why this is happening or better yet how I can properly send out one single message to every IP my service could possibly be on?

Thank you!
0
Comment
Question by:ehensens
[X]
Welcome to Experts Exchange

Add your voice to the tech community where 5M+ people just like you are talking about what matters.

  • Help others & share knowledge
  • Earn cash & points
  • Learn & ask questions
  • 10
  • 6
17 Comments
 
LVL 40

Expert Comment

by:mrjoltcola
ID: 24318817
.255 would be the broadcast address, but it is not a single IP/interface so you can't "connect" to it.

To broadcast you don't need to connect, you just need to open a socket from an interface and send to the broadcast address.
0
 

Author Comment

by:ehensens
ID: 24318861
Hi mrjoltcola,

Thank you for your response. I'm afraid I don't quite understand what you mean that I don't need to connect to it. How do I send to the broadcast address without connecting?

Thanks again!
0
 
LVL 40

Expert Comment

by:mrjoltcola
ID: 24318932
For example, with sendto() and UDP, you won't use connect(), you just use sendto().

Using the Berkeley socket call, sendto() allows you to pass the sockaddr structure in as the 5th argument, along with the address len. That is what differentiates sendto() from send() which operates on a connected socket.

You can use connect() on UDP sockets, but only if it is a valid IP address, which .255 and .0 are not. And connect() is only needed if you wish to then use send() without passing the 5th and 6th arguments as with sendto(). It might speed up things a bit, and make your socket code less cluttered, and I use it when I can in UDP programming.

Note the difference:

  ssize_t send(int s, const void *buf, size_t len, int flags);
  ssize_t sendto(int s, const void *buf, size_t len, int flags, const struct sockaddr *to, socklen_t tolen);

In your case, just pass the address, something like this, where toaddr is a "struct sockaddr" that contains the .255 network broadcast address.

sendto(fd, &datastruct, sizeof(datastruct), flags, &toaddr, sizeof(sockaddr));
0
Plug and play, no additional software required!

The ATEN UE3310 USB3.1 Gen1 Extender Cable allows users to extend the distance between the computer and USB devices up to 10 m (33 ft). The UE3310 is a high-quality, cost-effective solution for professional environments such as hospitals, factories and business facilities.

 
LVL 40

Expert Comment

by:mrjoltcola
ID: 24318962
You also need to use setsockopt(fd, SOL_SOCKET, SO_BROADCAST, ... ) or you may also get permission denied. This is from W. Richard Stevens book, _UNIX Network Programming_ which is probably the best single book you can own if you write networking software.

Even if using Windows, the old Berkeley sockets API still applies, mostly, so the book is very relevant and has a complete chapter on Broadcasting.

http://www.amazon.com/UNIX-Network-Programming-Networking-Sockets/dp/013490012X
0
 

Author Comment

by:ehensens
ID: 24318992
So do I call setsockopt() , sendto() , write() , read() in that order?
0
 
LVL 40

Expert Comment

by:mrjoltcola
ID: 24319133
That is the order, but sendto is in place of write, and recvfrom/recv is in place of read. No need for both. write cannot write to broadcast addresses, that I know of, as it just uses a descriptor, and since you cannot obtain a "connected descriptor" to a broadcast adderss, you cannot use write.

0
 
LVL 40

Expert Comment

by:mrjoltcola
ID: 24319152
0
 
LVL 40

Expert Comment

by:mrjoltcola
ID: 24319171
0
 

Author Comment

by:ehensens
ID: 24319354
Those are both great links but I don't see how the sender receives the response? Before I was just connect(), write(), and then read()

since i'm not doing connect() or write() now, just sendto(), how do I do the equivalent of "read()"?
0
 
LVL 40

Expert Comment

by:mrjoltcola
ID: 24319395
The sender would receive the response by calling recv on the socket. You can bind to that socket, and read from it. The 2nd link I provided does discuss that in the last message.
0
 

Author Comment

by:ehensens
ID: 24319405
Sorry, I guess I overlooked it. Let me give it a whirl!
0
 

Author Comment

by:ehensens
ID: 24319506
It just sits on recv() seemingly forever, I don't see what I'm doing wrong, do you?

    struct hostent *hostentPointer;
    
    hostentPointer = gethostbyname(broadcastHost);
   
    struct sockaddr_in serverAddress;
    
    char **pPointer;
    char networkAddress[A_NUMBER];
    
    int broadcast = 1;
       
    hostentPointer = gethostbyname(broadcastHost);
       
    pPointer = hostentPointer -> h_addr_list;
    
    inet_ntop(hostentPointer->h_addrtype, *pPointer, networkAddress, sizeof(networkAddress));
    
    int sockFD = socket(PF_INET, SOCK_DGRAM, 0);
    
    setsockopt(sockFD, SOL_SOCKET, SO_BROADCAST, &broadcast, sizeof(broadcast));
    
    bind(sockFD, (struct sockaddr*) &serverAddress, sizeof(serverAddress));
   
    bzero(&serverAddress, sizeof(serverAddress));
    serverAddress.sin_family = PF_INET;
    serverAddress.sin_port = htons(8004);
    inet_pton(AF_INET, networkAddress, &serverAddress.sin_addr);
 
    char sendRequest[SENDSIZE];
 
    char payload[SOME_NUMBER] = "";
        
    strcat(payload, "broadcastFunction");
    
    snprintf(sendRequest, BUFFSIZE,
            
             /* Actual HTTP POST text */
             "POST %s HTTP/1.0\r\n"
             "Host: %s\r\n"
             "Content-type: text/plain\r\n"
             "Content-length: %d\r\n\r\n"
             "%s", "Directory", broadcastHost, strlen(payload), payload);
    
 
 
    sendto(sockFD, sendRequest, strlen(sendRequest), 0, (struct sockaddr *) &serverAddress, sizeof(serverAddress));
 
 
    unsigned int msgLength = 10000;
   
    recv(sockFD, broadcastResponse, msgLength, 0);
    
    
    printf("\n\nBroadcast response:\n\n%s\n", broadcastResponse);

Open in new window

0
 
LVL 40

Expert Comment

by:mrjoltcola
ID: 24320936
Curious why you are broadcasting an HTTP POST.

Anyway, is your receiver showing anything, and is it responding?
0
 
LVL 4

Accepted Solution

by:
lhl60 earned 1000 total points
ID: 24323232
well I wouldn't use HTTP in the discovery

HTTP is meant for connection oriented stuff
I will suggest something like this:

Let your server listen for UDP packets on a "discover port"
and let it listen for TCP connects requests on a "production" port

on the client side
build a discovery routine

Send a UDP packet to the subnet (broadcast) on the "discover" port, the content can be something identifying the client (version,secret code....)

The server picks it up, and respond (UPD)  with  some previously agreed message content that allow your client to identify it as a valid server ( maybe even information about the production port, or some other useful information)

If a satisfactory answer to the broadcast arrives, within a reasonable timer limit. the client then  know the IP address of the server. and the client can initiate a normal  production connection (TCP).


0
 

Author Comment

by:ehensens
ID: 24325106
Sorry if my code is a little perplexing, I am brand new to networking. I've been POSTing information from my app to my service under normal running conditions, so I thought that for any kind of automatic "Find Service IP Address" feature I'd just do the same thing, only use a broadcast IP address instead of the service's specific IP. Then I found out that you can't connect() to a broadcast IP... I guess I'll just have to try to sludge through this...

I've gotten to the point where I can finally recv() from that socket now after I sendto() but it's just reading exactly what I sent, and my service is not responding. It seems I can only get my service to acknowledge communication when I write() to it...
0
 
LVL 40

Assisted Solution

by:mrjoltcola
mrjoltcola earned 1000 total points
ID: 24325998
broadcasting is connectionless, yes.

Typically you use it with UDP, then wait for responses, in packet mode, and the response can be from anyone. Stream mode won't work.

The POST you have is an HTTP request, which requires TCP level anyway. A listening TCP socket will never receive a broadcast, its impossible.
0
 
LVL 40

Expert Comment

by:mrjoltcola
ID: 24326001
Oh, sorry I did not see lhl60's response, he already explained.
0

Featured Post

Independent Software Vendors: We Want Your Opinion

We value your feedback.

Take our survey and automatically be enter to win anyone of the following:
Yeti Cooler, Amazon eGift Card, and Movie eGift Card!

Question has a verified solution.

If you are experiencing a similar issue, please ask a related question

Short answer to this question: there is no effective WiFi manager in iOS devices as seen in Windows WiFi or Macbook OSx WiFi management, but this article will try and provide some amicable solutions to better suite your needs.
This article will show how Aten was able to supply easy management and control for Artear's video walls and wide range display configurations of their newsroom.
Get a first impression of how PRTG looks and learn how it works.   This video is a short introduction to PRTG, as an initial overview or as a quick start for new PRTG users.
Michael from AdRem Software outlines event notifications and Automatic Corrective Actions in network monitoring. Automatic Corrective Actions are scripts, which can automatically run upon discovery of a certain undesirable condition in your network.…

730 members asked questions and received personalized solutions in the past 7 days.

Join the community of 500,000 technology professionals and ask your questions.

Join & Ask a Question