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.

Socket Problem

Empfohlene Antworten

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]

  • Autor

Ich hab grad festgestellt, dass wenn ich am Ende der Schleife 5-6 Sekunden warte, das Problem nicht auftritt. Da ich aber nicht solange warten kann bräuchte ich ne Idee wie ich das Umgehen kann. Anscheinend braucht Windows etwas Zeit das Socket anständig zu schließen.

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

  • Autor

Konnte das Problem gerade lösen. Es lag irgendwie daran, dass ich recv() aus irgendeinem Grund MSG_PEEK als letzten Parameter übergeben habe. Hab das jetzt durch NULL ersetzt und das Socket wird geschlossen, ohne das ich SO_DONTLINGER oder so setzen muss.

Gruß

Guybrush

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

Archiv

Dieses Thema wurde archiviert und kann nicht mehr beantwortet werden.

Konto

Navigation

Suchen

Suchen

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.