मुझे एक उदाहरण दें:
क्लाइंट सर्वर से कनेक्ट होता है, और हर 1 सेकंड में सर्वर को 1MB डेटा भेजता है।
सर्वर साइड एक कनेक्शन स्वीकार करते हैं, और फिर tcp send buffer
क्लाइंट से पुन: संदेश के बिना 20 सेकंड सोते हैं । ग्राहक पक्ष में पूर्ण हो जाएगा।
ग्राहक पक्ष में कोड:
#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];
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;
}
सर्वर साइड में कोड:
#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 test_full_sock_buf_1(){
int listenfd = socket(AF_INET, SOCK_STREAM, 0);
exit_if(listenfd<0, "create socket error");
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 r = ::bind(listenfd, (struct sockaddr *) &addr, sizeof(struct sockaddr));
exit_if(r<0, "bind socket error");
r = listen(listenfd, 100);
exit_if(r<0, "listen socket error");
struct sockaddr_in raddr;
socklen_t rsz = sizeof(raddr);
int cfd = accept(listenfd, (struct sockaddr *) &raddr, &rsz);
exit_if(cfd<0, "accept socket error");
sockaddr_in peer;
socklen_t alen = sizeof(peer);
getpeername(cfd, (sockaddr *) &peer, &alen);
printf("accept a connection from %s:%d\n", inet_ntoa(peer.sin_addr), ntohs(peer.sin_port));
printf("but now I will sleep 15 second, then exit");
sleep(15);
}
सर्वर साइड शुरू करें, फिर क्लाइंट साइड शुरू करें।
सर्वर साइड आउटपुट हो सकता है:
accept a connection from 127.0.0.1:35764
but now I will sleep 15 second, then exit
Process finished with exit code 0
ग्राहक पक्ष उत्पादन कर सकते हैं:
connect to server successsend: 1024000, erron: 0, Success
send: 1024000, erron: 0, Success
send: 1024000, erron: 0, Success
send: 552190, erron: 0, Success
send: -1, erron: 11, Resource temporarily unavailable
send: -1, erron: 11, Resource temporarily unavailable
send: -1, erron: 11, Resource temporarily unavailable
send: -1, erron: 11, Resource temporarily unavailable
send: -1, erron: 11, Resource temporarily unavailable
send: -1, erron: 11, Resource temporarily unavailable
send: -1, erron: 11, Resource temporarily unavailable
send: -1, erron: 11, Resource temporarily unavailable
send: -1, erron: 11, Resource temporarily unavailable
send: -1, erron: 11, Resource temporarily unavailable
send: -1, erron: 11, Resource temporarily unavailable
send: -1, erron: 104, Connection reset by peer
send: -1, erron: 32, Broken pipe
send: -1, erron: 32, Broken pipe
send: -1, erron: 32, Broken pipe
send: -1, erron: 32, Broken pipe
send: -1, erron: 32, Broken pipe
आप देख सकते हैं, क्योंकि सर्वर साइड क्लाइंट से डेटा रिकवर नहीं करता है, इसलिए जब क्लाइंट साइड tcp buffer
फुल हो जाता है, लेकिन आप अभी भी डेटा भेजते हैं, तो आपको Resource temporarily unavailable
त्रुटि मिल सकती है।