Socket an bestimmte Netzwerk Karte hängen
-
Hallo,
Ich habe ein kleines Problem mit meiner Socketprogrammierung. Mein Computer hat zwei Netzwerkkarten. Ich möchte mit dem UDP Socket auf einem bestimmten Interface senden. Weiß jemand wie das geht? Mein bisheriger Code:
void UDPServer::sendMessageInLoop(string message, int count, int sleepTime, string ip, string port) { int i=0; struct sockaddr_in ServerAddress; while(i<count) { fd=socket(PF_INET, SOCK_DGRAM, IPPROTO_UDP); if(fd==-1) { cerr<<"error couldnt create socket"<<endl; exit(1); } ServerAddress.sin_family=AF_INET; ServerAddress.sin_port= htons(atoi(port.c_str())); ServerAddress.sin_addr.s_addr=inet_addr(ip.c_str()); sendto(fd, message.c_str(), message.size(), 0, (struct sockaddr *) &ServerAddress, sizeof(ServerAddress)); i++; } close(fd); }
dank und gruss,
flambert
-
-
Hört sich eigentlich schon nachdem an was ich bräuchte. Aber leider bekomme ich es nicht zum laufen. Mein Code sieht nun so aus:
/* * TCPServer.cpp * * Created on: 20.04.2010 */ #include "TCPServer.h" using namespace std; TCPServer::TCPServer() { connection_ok=-1; } void TCPServer::sendMessageInLoop(string message, int count, int sleepTime, string ip, string port) { int size_sent; struct sockaddr_in ServerAddress; struct ifreq interface; if(connection_ok!=0) { fd=socket(AF_INET, SOCK_STREAM, IPPROTO_TCP); if(fd==-1) { std::cerr<<"error couldnt create socket"<<std::endl; exit(1); } ServerAddress.sin_family=AF_INET; ServerAddress.sin_port= htons(8080); ServerAddress.sin_addr.s_addr=inet_addr("192.168.180.2"); strncpy(interface.ifr_ifrn.ifrn_name, "eth1", IFNAMSIZ); if (setsockopt(fd, SOL_SOCKET, SO_BINDTODEVICE, (char *)&interface, sizeof(interface)) < 0) { cout << SOL_SOCKET << endl; cout << SO_BINDTODEVICE << endl; cout << (char *)&interface << endl; perror("SO_BINDTODEVICE failed"); /* Deal with error... */ } connection_ok=connect(fd,(sockaddr *)&ServerAddress ,sizeof(ServerAddress)); cout << connection_ok << endl; if(connection_ok==-1) { std::cerr<<"unable to connect"<<std::endl; exit(1); } } int i=0; while(i<count) { size_sent = send(fd, message.c_str(), message.size(), 0); i++; } //close(fd); } TCPServer::~TCPServer() { try { close(fd); } catch(...){} }
-
flambert schrieb:
Aber leider bekomme ich es nicht zum laufen.
Was heißt das nun konkret?
edit:
achso, es scheint nicht für UDP zu funktionieren. Siehe man: socket(7)It is not supported for packet sockets (use normal bind(8) there).
Du solltest aber trotzdem lernen, Fehler besser zu beschreiben
.
-
Sorry. Die genaue Fehlerbeschreibung habe ich irgendwie verpennt. Ich habe den Titel auch nochmal geändert, da ich einen Client/Server für TCP und UDP schreiben muss. Das eben gepostete ist mein TCP Client. Und ich bekomme einfach die Fehlermeldung:
SO_BINDTODEVICE failed: Operation not permitted (das ist ja die selbstgeschriebene)
Ich habe außerdem mal nachgesehen was in den anderen Variablen so steht:
SOL_SOCKET: 0
SO_BINDTODEVICE: 25
(char *)&interface: eth0Kann sich jemand vorstellen was da schief läuft?
-
rüdiger schrieb:
It is not supported for packet sockets (use normal bind(8) there).
wenn eine dieser funktionen fehlschlägt, wird idr. zusätzlich zum return wert noch die globale variable "errno" gesetzt.
diese kannst du dann zusätzlich ausgeben lassen. dann weißt du auch was da schief gelaufen ist und nicht nur das es so ist.lg lolo
-
Wenn ich:
cout << errno << endl;
schreibe bekomme ich die Ausgabe "22". Das hilft mir gerade auch nicht so recht weiter.
-
da solltest eigentlich fündig werden, wenn ich jetzt die richtigen dateien erwischt hab. das immer so ne sache
http://lxr.linux.no/#linux+v2.6.33/include/asm-generic/errno-base.h
http://lxr.linux.no/#linux+v2.6.33/include/asm-generic/errno.hlg lolo
-
Es bringt mich immer weiter. Allerdings führt das bei mir zu immer weiteren Fragen. In der Doku steht "Invalid Argument"... Hmmm.. Aber wie bekomme ich jetzt heraus welches Argument Invalid ist?
-
flambert schrieb:
Aber wie bekomme ich jetzt heraus welches Argument Invalid ist?
dafür brauchst ne glaskugel :p
als 3. prarmeter wird eigentlich kein struct sondern der string übergeben, ist zumindest bei ein paar source files so die mir google eben raus gelassen hat. da der aber in dem struct an erster stelle steht sollte das kein problem darstellen. das sizeof() nimmt aber jetzt die größe des structs und das wäre zuviel. versuch mal als 4. parameter sizeof("eth1") evtl. hilft das was.
lg lolo
-
http://stackoverflow.com/questions/1207746/problems-with-so-bindtodevice-linux-socket-option
noobLolo schrieb:
rüdiger schrieb:
It is not supported for packet sockets (use normal bind(8) there).
wenn eine dieser funktionen fehlschlägt, wird idr. zusätzlich zum return wert noch die globale variable "errno" gesetzt.
diese kannst du dann zusätzlich ausgeben lassen. dann weißt du auch was da schief gelaufen ist und nicht nur das es so ist.lg lolo
Das macht er doch bereits mit man: perror!