Viele Fragen zu WinSock...
-
Netzwerknoob schrieb:
Badestrand schrieb:
Du musst abfragen, wieviel gesendet/empfangen wurde (steht übrigens auch in der MSDN).
Es ist sehr schlecht dokumentiert. Es gibt nämlich Unterschiede zwischen UDP/TCP, nur weiß ich nicht mehr welche. Bei einem der beiden kann man sich AFAIR darauf verlassen, dass die Funktionen send/recv/... mit einem call alle Daten verarbeiten (=senden/empfangen?).
Zu "send":
MSDN schrieb:
If no error occurs, send returns the total number of bytes sent, which can be less than the number indicated by len.
Und zu UDP noch:
MSDN schrieb:
For message-oriented sockets, care must be taken not to exceed the maximum packet size of the underlying provider, which can be obtained by using getsockopt to retrieve the value of socket option SO_MAX_MSG_SIZE. If the data is too long to pass atomically through the underlying protocol, the error WSAEMSGSIZE is returned, and no data is transmitted.
Hört sich wirklich so an, als würde bei UDP entweder alles oder garnix gesendet werden. Hoffe, jemand weiß es noch genauer.
Der Unterschied zwischen blocking<->non-blocking ist bei send/recv nur, dass du bei non-blocking warten musst bis der Socket bereit ist.
-
Die Socket-Funktionen sind soweit ich weiss sehrwohl Thread-Safe. Natürlich nur, wenn du den "rohen" Socket verwendest. Sobald du irgendwelche Wrapper-Klassen verwendest, musst du wissen ob diese Klassen Thread-Safe sind (was sie oft nicht sind).
Was UDP angeht: ja, UDP ist "alles oder nichts". Liegt in der Natur der Sache.
Weiters reicht bei UDP ein Socket um mit vielen Peers zu kommunizieren.
-
Aha ok super, danke!
Was ich nun bei Completion Ports nicht verstehe, ist, dass man anscheinend auf I/O, also beides, warten soll/kann?
Wie soll man auf einen Output warten? Ich dachte, damit wartet man, bis ein Client etwas schickt, also man wartet immer nur auf Input... Senden kann man doch, wann man will (Sobald die Verbindung steht)?MfG,
Der Netzwerknoob
-
Netzwerknoob schrieb:
Wie soll man auf einen Output warten? Ich dachte, damit wartet man, bis ein Client etwas schickt, also man wartet immer nur auf Input... Senden kann man doch, wann man will (Sobald die Verbindung steht)?
wenn die gegenstation die daten zu langsam abholt und dein sendebuffer voll ist, dann musste warten, bis es weitergeht.

-
Aha, aber GetQueuedCompletionStatus() ist doch ein blocking call. Wie soll ich da vernünftig senden können (Wenn ich zB. per Button-Klick etwas senden möchte)?
MfG,
Der Netzwerknoob
-
Achso, ich denke, ich kapiere es jetzt. Man sendet und sollte dann erst auf eine Output-Completion warten. Wenn dort dann was schief läuft, könnte der Sendepuffer voll sein oder sonst was fehlschlagen...
MfG,
Der Netzwerknoob
-
Netzwerknoob schrieb:
Aha, aber GetQueuedCompletionStatus() ist doch ein blocking call. Wie soll ich da vernünftig senden können (Wenn ich zB. per Button-Klick etwas senden möchte)?
die funktion ist doch für 'nen extra thread gedacht. der kann ruhig warten, bis das ereignis eintritt. kannst auch 'nen timeout angeben: http://msdn.microsoft.com/en-us/library/aa364986.aspx

-
Jo danke, aber das weiß ich schon.
Habe nun paar Tutorials gelesen, kapiere es aber nicht. Warum ist AcceptEx() so doof designed, dass gleich ein receive mit eingebaut ist? Verstehe ich das richtig, dass ich noch einen extra Thread brauche, welcher nach "stale clients" prüft, also clients, die sich verbunden, aber noch nix gesendet haben (DoS Attack)?
Und soll man nun einen oder mehrere Threads mit AcceptEx() verwenden? Wenn nämlich gerade ein client verbindet, aber noch nix sendet, können doch keine anderen clients verbinden...
(Vielleicht ein Tutorial, wo nicht so kryptische Kacke (oder MFC) wie hier http://msdn.microsoft.com/en-us/magazine/bb985148.aspx verwendet wird? (OverlapPlus, Overlap, OVERLAPPEDPLUS, ol, in einer Zeile, toll...))

MfG,
Der Netzwerknoob
-
Warum ist AcceptEx() so doof designed, dass gleich ein receive mit eingebaut ist?
das receive ist doch optional
-
Oh, das ging mir aus dem Tutorial irgendwie nicht hervor. Auch verwirrt mich dort, warum "socket(AF_INET, SOCK_STREAM, 0);" geschrieben wird und nicht "WSASocket(AF_INET, SOCK_STREAM, 0, 0, 0, WSA_FLAG_OVERLAPPED);".
MfG,
Der Netzwerknoob
-
Und warum muss anscheinend irgend ein Funktionszeiger von AcceptEx() geholt werden? Reicht es nicht, einfach die Funktion aufzurufen?

MfG,
Der Netzwerknoob
-
Reicht, ist aber langsamer.
-
Ok danke, bleiben noch 3 Fragen.
MfG,
Der Netzwerknoob
-
Öh sorry, eigentlich ... brauche ich nur ein ordentliches Tutorial...
MfG,
Der Netzwerknoob
-
Wie ist das mit AcceptEx(), muss ich das so machen:
Einmal beim Start des Programmes, und dann immer bei GetQueuedCompletionStatus() und OP_ACCEPT gleich ein neues AcceptEx() aufrufen?
Gibt es da dann keine Lücke, wo ein Client keine acception bekommt?MfG,
Der Netzwerknoob
-
Die Listen Queue ist doch auch noch da.
-
Ich weiß nicht, was du meinst.
MfG,
Der Netzwerknoob
-
Und für WSARecv() muss ich das dann doch auch so machen. Wie kann das performant sein? Wenn es fertig ist, ein neues WSARecv() aufrufen usw...
MfG,
Der Netzwerknoob
-
Netzwerknoob schrieb:
Einmal beim Start des Programmes, und dann immer bei GetQueuedCompletionStatus() und OP_ACCEPT gleich ein neues AcceptEx() aufrufen?
Gibt es da dann keine Lücke, wo ein Client keine acception bekommt?Windows puffert für die die eingehenden Verbindungen, auch wenn gerade kein accept ausständig ist.
-
[quote="Badestrand"]
Zu "send":
MSDN schrieb:
If no error occurs, send returns the total number of bytes sent, which can be less than the number indicated by len.
Das geht noch weiter. Ganz versteckt in einem kleinen Satz heißt es:
MSDN schrieb:
On nonblocking stream oriented sockets, the number of bytes written can be between 1 and the requested length ...
Wenn man mit einem blockierenden Socket send aufruft, wird immer alles gesendet. Im Gegensatz dazu kommt nicht zwangsläufig bei einem recv auch alles gesendete an.