Reputation: 4115
Im currently working with socket programming, but i am having problems connecting to my device when testing code on a computer with multiple ethernet devices.
How can i define which ethernet device it should be using (Mac OS X)?
Source:
int sock, bytes_recieved;
char send_data[1024],recv_data[1024];
struct hostent *host;
struct sockaddr_in server_addr;
host = gethostbyname("192.168.100.4");
cout << "Start" << endl;
if ((sock = socket(AF_INET, SOCK_STREAM, 0)) == -1) {
// perror("Socket");
cout << "Socket error" << endl;
exit(1);
}
server_addr.sin_family = AF_INET;
server_addr.sin_port = htons(30002);
server_addr.sin_addr = *((struct in_addr *)host->h_addr);
bzero(&(server_addr.sin_zero),8);
if (connect(sock, (struct sockaddr *)&server_addr,
sizeof(struct sockaddr)) == -1)
{
// perror("Connect");
cout << "Connect error" << endl;
exit(1);
}
Thanks in advance.
Upvotes: 1
Views: 1890
Reputation: 1364
There are 2 identical ends to a TCP connection, and once established are indistinguishable from each other. Both ends have an IP address and a port number, which the other computer must send data to.
The connect
function tells the client the IP address and port that the server is listening on
The bind
function tells the client which IP address and port it should listen on for replies from the server. If you don't call bind()
the operating system will automatically choose suitable values.
The issue you are having (from what you have said) is that the operating system is choosing the wrong default IP address. This is where the bind function comes in.
Below is a (untested) fixed up copy of your code which binds to the address of 192.168.100.2
. You will need to change this to the address belonging to the interface you want to use.
If you open a terminal and enter ifconfig -a
it will print a list of all interfaces and the IP address(es) belonging to each. You should replace the value 192.168.100.2
in the following code with an IP address belonging to the interface you wish to use.
int sock, bytes_recieved;
char send_data[1024],recv_data[1024];
struct hostent *host;
struct sockaddr_in server_addr, local_addr; //Added a new variable in here for our local address
host = gethostbyname("192.168.100.4"); //This is the address of the server we are connecting to
cout << "Start" << endl;
if ((sock = socket(AF_INET, SOCK_STREAM, 0)) == -1) {
// perror("Socket");
cout << "Socket error" << endl;
exit(1);
}
//Now we want to bind an IP address
//This is an IP address that belongs to your computer, that will be used as the reply IP address
local_addr.sin_family = AF_INET;
local_addr.sin_addr.s_addr = inet_addr("192.168.100.2"); //CHANGE THIS: this is an address on your computer
local_addr.sin_port = htons(0); //Leave this as 0 and the operating system will choose a unused one for you
if bind(sock, (struct sockaddr *)&local_addr, sizeof(local_addr)) == -1)
{
// perror("Bind");
cout << "Bind error" << endl;
exit(1);
}
//Set up the structure that tells us what server to connect to
server_addr.sin_family = AF_INET;
server_addr.sin_port = htons(30002);
server_addr.sin_addr = *((struct in_addr *)host->h_addr);
bzero(&(server_addr.sin_zero),8);
//And connect to the server
if (connect(sock, (struct sockaddr *)&server_addr,
sizeof(struct sockaddr)) == -1)
{
// perror("Connect");
cout << "Connect error" << endl;
exit(1);
}
Upvotes: 2
Reputation: 1364
You can specify the listening address with the bind function.
An address of 0.0.0.0 is used to listen on all interfaces and IP addresses belonging to the computer, alternatively you can specify a specific IP address to listen on, which will select only the interface that address belongs to
EDIT: The MSDN example at the bottom of the page is easier to follow
Upvotes: 3