Was kann eine „Ressource vorübergehend nicht verfügbar“ beim Befehl sock send() verursachen
Lesezeit: 6 Minuten
Giroy
Wodurch kann a Resource temporarily unavailable Fehler auf einem Socket send() Befehl? Die Buchse ist eingerichtet als AF_UNIX, SOCK_STREAM. Es funktioniert die meiste Zeit, aber gelegentlich tritt dieser Fehler auf. Das empfangende Ende des Sockets scheint ordnungsgemäß zu funktionieren.
Ich weiß, das ist nicht sehr detailliert, aber ich suche nur nach allgemeinen Ideen. Vielen Dank!
Ist das verwandt? stackoverflow.com/questions/5737493/…
– Reisfeld
17. Januar 2013 um 0:52 Uhr
Setzen Sie Ihren Socket auf O_NONBLOCK?
– Deepankar Bajpeyi
17. Januar 2013 um 0:57 Uhr
Ich glaube nicht, dass es mit diesem Beitrag zusammenhängt. Meine Sockets sind SOCK_STREAM, von denen ich glaube, dass sie blockieren, was ich will.
– giro
17. Januar 2013 um 0:59 Uhr
Ob ein Stream blockiert oder nicht blockiert, ist unabhängig davon, ob es sich um SOCK_STREAM oder SOCK_DGRAM handelt. Die Antwort dort ist relevant.
– Barmar
17. Januar 2013 um 1:33 Uhr
"Resource temporarily unavailable" ist die entsprechende Fehlermeldung EAGAIN, was bedeutet, dass der Vorgang blockiert wäre, aber ein nicht blockierender Vorgang angefordert wurde. Zum send()das könnte an Folgendem liegen:
explizites Markieren des Dateideskriptors als nicht blockierend mit fcntl(); oder
vorbei an der MSG_DONTWAIT Flagge zu send(); oder
Einstellen eines Sende-Timeouts mit der SO_SNDTIMEO Steckdosenoption.
Die Ursache meines Problems war das Einstellen des Sende-Timeouts. Danke für deine Hilfe!
– giro
17. Januar 2013 um 22:58 Uhr
@caf, In meinem Fall führte eine unterschiedliche MTU-Größenkonfiguration auf zwei Seiten dazu, dass die sctp-Assoziations-Txqueue überflog, wenn eine hohe Paketaustauschrate stattfand. Wenn Sie die MTU auf beiden Systemen gleich machten, verschwand das Problem. Aber kann mir bitte jemand erklären, was der Grund für das Problem ist?
– Codename_DJ
23. Januar 2017 um 12:22 Uhr
Warum verursacht das Setzen von SO_SNDTIMEO den Fehler? Wie verwendet man diese Flagge richtig?
– Gabriel Fernández
27. April 2021 um 20:10 Uhr
@GabrielFernandez: Weil das was ist SO_SNDTIMEO Anfragen: dass die Sendung nicht länger als die Timeout-Periode blockiert. Wenn das Senden nicht abgeschlossen ist und das Timeout abläuft, wird es zurückgegeben EAGAIN um diesen Zustand anzuzeigen. Wie Sie damit umgehen, hängt von Ihrer Bewerbung ab, wobei zu beachten ist, dass die von Ihnen versuchten Daten nicht gesendet wurden.
– Café
28. April 2021 um 7:13 Uhr
Das liegt daran, dass Sie a verwenden non-blocking Socket und der Ausgabepuffer ist voll.
Von dem send() Manpage
When the message does not fit into the send buffer of the socket,
send() normally blocks, unless the socket has been placed in non-block-
ing I/O mode. In non-blocking mode it would return EAGAIN in this
case.
WIEDER ist der zugehörige Fehlercode “Ressource vorübergehend nicht verfügbar”
Erwägen Sie die Verwendung select() eine bessere Kontrolle über dieses Verhalten zu bekommen
@giroy: aber eigentlich nicht richtig … eigentlich a Blockierung Steckdose, mit SO_SNDTIMEO
– EML
12. Juli 2018 um 7:22 Uhr
Cool, aber wie können wir eine andere Verbindung verwenden, um das gleichzeitige Lesen in der DB zu verwalten?
– MUY Belgien
16. September 2019 um 12:09 Uhr
Lassen Sie mich ein Beispiel geben:
Der Client stellt eine Verbindung zum Server her und sendet alle 1 Sekunde 1 MB Daten an den Server.
Die Serverseite akzeptiert eine Verbindung und schläft dann 20 Sekunden lang ohne Empfangsnachricht vom Client.So die tcp send buffer auf der Clientseite wird voll sein.
Code auf der Clientseite:
#include <arpa/inet.h>
#include <sys/socket.h>
#include <stdio.h>
#include <errno.h>
#include <fcntl.h>
#include <stdlib.h>
#include <string.h>
#define exit_if(r, ...) \
if (r) { \
printf(__VA_ARGS__); \
printf("%s:%d error no: %d error msg %s\n", __FILE__, __LINE__, errno, strerror(errno)); \
exit(1); \
}
void setNonBlock(int fd) {
int flags = fcntl(fd, F_GETFL, 0);
exit_if(flags < 0, "fcntl failed");
int r = fcntl(fd, F_SETFL, flags | O_NONBLOCK);
exit_if(r < 0, "fcntl failed");
}
void test_full_sock_buf_1(){
short port = 8000;
struct sockaddr_in addr;
memset(&addr, 0, sizeof addr);
addr.sin_family = AF_INET;
addr.sin_port = htons(port);
addr.sin_addr.s_addr = INADDR_ANY;
int fd = socket(AF_INET, SOCK_STREAM, 0);
exit_if(fd<0, "create socket error");
int ret = connect(fd, (struct sockaddr *) &addr, sizeof(struct sockaddr));
exit_if(ret<0, "connect to server error");
setNonBlock(fd);
printf("connect to server success");
const int LEN = 1024 * 1000;
char msg[LEN]; // 1MB data
memset(msg, 'a', LEN);
for (int i = 0; i < 1000; ++i) {
int len = send(fd, msg, LEN, 0);
printf("send: %d, erron: %d, %s \n", len, errno, strerror(errno));
sleep(1);
}
}
int main(){
test_full_sock_buf_1();
return 0;
}
Sie können sehen, dass die Serverseite die Daten nicht vom Client empfängt, also wenn die Clientseite tcp buffer voll werden, aber Sie senden immer noch Daten, damit Sie möglicherweise erhalten Resource temporarily unavailable Error.
Es gibt einen anderen Fall, der Fehler 11 verursachen kann Resource temporarily unavailable
Wenn das Protokoll der Anwendungsschicht http ist, wird die TCP-Verbindung nach dem erfolgreichen Empfang der ersten http-Antwort standardmäßig nicht geschlossen, der Anrufempfang wird erneut blockiert und -1 wird von recv zurückgegeben, wenn SO_RCVTIMEO abgelaufen ist, errno wird gesetzt 11
14208300cookie-checkWas kann eine „Ressource vorübergehend nicht verfügbar“ beim Befehl sock send() verursachenyes
Ist das verwandt? stackoverflow.com/questions/5737493/…
– Reisfeld
17. Januar 2013 um 0:52 Uhr
Setzen Sie Ihren Socket auf O_NONBLOCK?
– Deepankar Bajpeyi
17. Januar 2013 um 0:57 Uhr
Ich glaube nicht, dass es mit diesem Beitrag zusammenhängt. Meine Sockets sind SOCK_STREAM, von denen ich glaube, dass sie blockieren, was ich will.
– giro
17. Januar 2013 um 0:59 Uhr
Ob ein Stream blockiert oder nicht blockiert, ist unabhängig davon, ob es sich um SOCK_STREAM oder SOCK_DGRAM handelt. Die Antwort dort ist relevant.
– Barmar
17. Januar 2013 um 1:33 Uhr