2009-05-05 9 views
1

ich diesen Code in meinem Socket-Klasse haben:binden kann nicht zu niedrig Portnummer (80) auf XP sp3

bool GSocket::Listen(int Port) 
{ 
    d->Socket = socket(AF_INET, SOCK_STREAM, 0); 
    if (d->Socket >= 0) 
    { 
     sockaddr Addr; 
     sockaddr_in *a = (sockaddr_in*) &Addr; 
     ZeroObj(Addr); 
     a->sin_family = AF_INET; 
     a->sin_port = htons(Port); 
     a->sin_addr.OsAddr = INADDR_ANY; 

     if (bind(d->Socket, &Addr, sizeof(Addr)) >= 0) 
     { 
      if (listen(d->Socket, SOMAXCONN) != SOCKET_ERROR) 
      { 
       return true; 
      } 
      else 
      { 
       Error(); 
      } 
     } 
     else 
     { 
      Error(); 
     } 
    } 
    else 
    { 
     Error(); 
    } 

    return false; 
} 

Der „Fehler()“ Methode nur ruft WSAGetLastError und übergibt den Fehler und Es ist eine Beschreibung bis zur App. Wie auch immer, es funktioniert gut auf meinem Rechner (xp sp2), aber scheitert auf meiner Freunde xp sp3 Maschine. Insbesondere schlägt der Bindungsaufruf fehl und WSAGetLastError gibt "2" zurück, was nicht einmal ein gültiger Socket-Fehlercode ist. Der Wert von "Port" ist 80, ich benutze einen einfachen HTTP-Server als UI für einen Dienst. Ich bin mir nicht ganz sicher, warum ich nach> = 0 suche, aber es könnte mit Nicht-Windows-Plattformen zusammenhängen, auf denen ich auch diesen Code verwende. In jedem Fall laut MSDN der Return-Code bei Fehler für die Bindung ist SOCKET_ERROR, die -1 ist, so dass die Prüfung in Ordnung sein sollte.

Habe ich etwas Einfaches verpasst?

Update: Wir haben gerade eine andere Portnummer '8888' versucht und alles funktioniert wie erwartet. Es scheint also, dass die niedrige Portnummer das Problem ist. Es gibt nichts, das aktiv auf diesem Port hört, bevor wir meinen Dienst ausführen, also denke ich, dass es ein neues Berechtigungsproblem in SP3 ist, das Prozesse abstößt, die auf Ports < 1024 abhören, es sei denn sie haben bestimmte Berechtigungen, die dem Linux/Unix-Weg ähneln Dinge tun. Trotzdem würde ich gerne in der Lage sein, es trotzdem zu lösen.

+0

Können Sie tatsächlich echte Sockets mit WinSock Sockets auf diese Weise mischen? Ich hätte gedacht, Ihre Methode sollte entweder errno oder WSA Anrufe für Socket/bind/listen/... – paxdiablo

+0

Ich bin mir ziemlich sicher, dass Sie die Anrufe mischen können, ich habe noch nie etwas Gegenteiliges gesehen. Und mein Code funktioniert schon lange so. YMMV – fret

+0

Können Sie bitte den letzten Absatz der Frage (Ihr Update) auf eine Antwort verschieben und akzeptieren? Dies wird immer noch in der "Unanswered" -Liste angezeigt. Vielen Dank. –

Antwort

2

Portnummern im Bereich von 0 bis 1023 sind well known ports und das Betriebssystem kann Administratorrechte erfordern, um an sie gebunden zu sein. Folglich muss jede Anwendung, die versucht, diese Ports zu verwenden, privilegiert sein.

+0

Dies sind nur zusätzliche Informationen. Was ich wissen muss ist, wie bekomme ich diese Berechtigungen? – fret

+0

Für UNIX muss das Programm im Besitz von root und setuid sein (d. H. Das Set-UID-Bit muss aktiviert sein). Ich weiß nicht über Windows. –

+0

Unter Windows kann der Prozess Administratorrechte über ein Manifest anfordern. Dann können Sie Ports <1024 verwenden. – fret

0

Sie machen lustige Zeigerarithmetik dort ... einfach eine sockaddr_in auf den Stapel legen und einen Zeiger übergeben, um zu binden.

sockaddr_in a = {0}; 
a.sin_family = AF_INET; 
a.sin_port = htons(Port); 
a.sin_addr.OsAddr = INADDR_ANY; 

if (bind(d->Socket, (sockaddr *) &a, sizeof(a)) >= 0) 

Versuchen Sie auch zu überprüfen, ob Privilegien in die Quere kommen. Ist an diesem Port bereits etwas geöffnet (fragen Sie netstat)

+0

Nichts nutzt den Port bereits (wir tcpview verwendet) und ich denke, Dauerwellen sind das Problem, aber wie man die Rechte perms bekommt, um den Sockel zu öffnen? Das ist die Nuss der Frage. – fret

Verwandte Themen