Zum Inhalt springen
View in the app

A better way to browse. Learn more.

Fachinformatiker.de

A full-screen app on your home screen with push notifications, badges and more.

To install this app on iOS and iPadOS
  1. Tap the Share icon in Safari
  2. Scroll the menu and tap Add to Home Screen.
  3. Tap Add in the top-right corner.
To install this app on Android
  1. Tap the 3-dot menu (⋮) in the top-right corner of the browser.
  2. Tap Add to Home screen or Install app.
  3. Confirm by tapping Install.

Empfohlene Antworten

Veröffentlicht

Hi,

ich hab eine Serveranwendung bei der ich mir ein Socket anlege und mit diesem in einer Schleife auf einem Port auf Verbindungsanfragen warte. Nach dem eine Verbindung mit einem Client aufgebaut wurde, erhält die Anwendung einen String, verarbeitet diesen und sendet eine Antwort zurück. Im Moment schließe ich das Socket welches ich mit accept() erhalte am Ende der Schleife nicht, allerdings scheint accept() irgendwann nicht mehr zurückzukehren, was ich darauf zurückführe das ich das Socket nicht schließe und Resourcen nicht freigegeben werden.

Wenn ich das Socket aber mit closesocket() am Ende der Schleife schließe, tritt kein Fehler auf, die Anwendung nimmt aber jede Anfrage 10 mal entgegen und verarbeitet diese. Hat jemand eine Idee woran das liegen könnte?

Gruß

Guybrush

Hallo,

poste doch mal Deinen Code, das macht die Fehlersuche einfacher.

Accept arbeitet nur mit Stream-Sockets und wird nur zum Aufbau der Verbindung verwendet. Es liefert einen socket zurück, dann der zum Lesen und Schreiben verwendet wird. Wenn Du jetzt bei jedem Aufruf ein accept() ausführst, gehen Dir irgendwann die Filedescriptoren aus. Das heisst, du solltest am Ende der Verbindung den Kommunikationssocket auch schliessen.

Nic

  • Autor

Etwas verkürzt sieht der Code so aus:


WORD Version = MAKEWORD(2,2);
WSADATA WsaData;
if (WSAStartup(Version,&WsaData) != NULL)
//fehler

if (LOBYTE(WsaData.wVersion) != 2 ||
HIBYTE(WsaData.wVersion != 2))
//fehler

g_.ServerSocket = socket(AF_INET,SOCK_STREAM,0);
if (g_.ServerSocket == INVALID_SOCKET)
//fehler

g_.SvrAddr.sin_family = AF_INET;
g_.SvrAddr.sin_addr.s_addr = INADDR_ANY;
g_.SvrAddr.sin_port = htons(5001);
if (bind(g_.ServerSocket,(LPSOCKADDR)&g_.SvrAddr,sizeof(sockaddr_in)) == SOCKET_ERROR)
//fehler

while (true)
{
if (listen(g_.ServerSocket,1) == SOCKET_ERROR)
//fehler


addr_len = sizeof(sockaddr_in);
g_.ClientSocket = accept(g_.ServerSocket,(LPSOCKADDR)&CliAddr,&addr_len);

if (g_.ClientSocket == INVALID_SOCKET)
//fehler

if ((nBytes = recv(g_.ClientSocket,szString,600,MSG_PEEK)) == SOCKET_ERROR)
//fehler

/*Datenverarbeitung*/


send(g_.ClientSocket,strAntwort,strlen(strAntwort),NULL);


//if (closesocket(g_.ClientSocket) == SOCKET_ERROR)
//fehler
}
...
[/PHP]

Hallo,

es gibt generell unterschiedliche Möglichkeiten, einen Socket zu schliessen (wird über die Optionen SO_[DONT]LINGER gesteuert). Für Windows schau mal hier:

http://msdn.microsoft.com/library/default.asp?url=/library/en-us/winsock/winsock/graceful_shutdown_linger_options_and_socket_closure_2.asp

Das Problem tritt wahrscheinlich dann auf, wenn der Client den Socket noch nicht geschlossen hat.

Nic

Hallo,

Original geschrieben von Guybrush Threepwood

Es lag irgendwie daran, dass ich recv() aus irgendeinem Grund MSG_PEEK als letzten Parameter übergeben habe.

"Irgendwie" ist nett formuliert :) Die Option "MSG_PEEK" führt dazu, dass die Daten zwar in dem recv()-Aufruf zurückgeliefert, jedoch nicht aus der Empfangqueue entfernt werden. Beim nächsten Aufruf werden die Daten nochmals zurück geliefert.

Nic

Erstelle ein Konto oder melde dich an, um einen Kommentar zu schreiben.

Configure browser push notifications

Chrome (Android)
  1. Tap the lock icon next to the address bar.
  2. Tap Permissions → Notifications.
  3. Adjust your preference.
Chrome (Desktop)
  1. Click the padlock icon in the address bar.
  2. Select Site settings.
  3. Find Notifications and adjust your preference.