seeyou_shj 发表于 2020-1-8 15:34

win7系统级socket缓冲区有多大?

本帖最后由 seeyou_shj 于 2020-1-8 15:36 编辑

进行网络程序极限测试时发现,通过调用socket发送/接收数据,有时候会有接收到的数据包里面的数据部分丢失的情况,应该是系统默认的socket缓冲区太小导致。网上搜了一下如何设置系统默认的缓冲区大小设置,找到一些资料,比如
[*][HKEY_LOCAL_MACHINE \SYSTEM \CurrentControlSet\Services\Afd\Parameters]
[*]
[*]DefaultReceiveWindow = 1800 (16进制)
[*]DefaultSendWindow = 1800(16进制)
[*]可以设置Windows7修改socket默认缓冲区大小。

有个问题,不对其进行设置的情况下,默认的系统缓冲区有多大呢?是不是跟电脑内存有关?也就是说内存越大,系统默认的socket缓冲区越大?请大佬帮忙解惑,多谢!

禁闭岛 发表于 2020-1-8 16:14

可以调用getsockopt函数设置SO_RCVBUF来获取

seeyou_shj 发表于 2020-1-9 09:00

从MSDN官方网站找了个程序,测试了一下,结果返回0.
代码如下:
#include <stdio.h>
#include <winsock2.h>
#include <windows.h>

int main() {

//---------------------------------------
// Declare variables
WSADATA wsaData;
SOCKET ListenSocket;
sockaddr_in service;

//---------------------------------------
// Initialize Winsock
int iResult = WSAStartup( MAKEWORD(2,2), &wsaData );
if( iResult != NO_ERROR )
    printf("Error at WSAStartup\n");

//---------------------------------------
// Create a listening socket
ListenSocket = socket( AF_INET, SOCK_STREAM, IPPROTO_TCP );
if (ListenSocket == INVALID_SOCKET) {
    printf("Error at socket()\n");
    WSACleanup();
    return 0;
}

//---------------------------------------
// Bind the socket to the local IP address
// and port 27015
hostent* thisHost;
char* ip;
u_short port;
port = 27015;
thisHost = gethostbyname("");
ip = inet_ntoa (*(struct in_addr *)*thisHost->h_addr_list);

service.sin_family = AF_INET;
service.sin_addr.s_addr = inet_addr(ip);
service.sin_port = htons(port);

if ( bind( ListenSocket,(SOCKADDR*) &service, sizeof(service) )== SOCKET_ERROR ) {
    printf("bind failed\n");
    closesocket(ListenSocket);
    return 0;
}

//---------------------------------------
// Initialize variables and call getsockopt.
// The SO_ACCEPTCONN parameter is a socket option
// that tells the function to check whether the
// socket has been put in listening mode or not.
// The various socket options return different
// information about the socket. This call should
// return 0 to the optVal parameter, since the socket
// is not in listening mode.
int optVal;
int optLen = sizeof(int);

if (getsockopt(ListenSocket,
    SOL_SOCKET,
    SO_ACCEPTCONN,
    (char*)&optVal,
    &optLen) != SOCKET_ERROR)
    printf("SockOpt Value: %ld\n", optVal);

//---------------------------------------
// Put the listening socket in listening mode.
if (listen( ListenSocket, 100 ) == SOCKET_ERROR) {
    printf("error listening\n");
}

//---------------------------------------
// Call getsockopt again to verify that
// the socket is in listening mode.
if (getsockopt(ListenSocket,
    SOL_SOCKET,
    SO_ACCEPTCONN,
    (char*)&optVal,
    &optLen) != SOCKET_ERROR)
    printf("SockOpt Value: %ld\n", optVal);

WSACleanup();
return 0;
}

禁闭岛 发表于 2020-1-9 09:30

SO_ACCEPTCONN这个选项是用来判断socket是否处于监听状态,程序的输出是正确的啊。

禁闭岛 发表于 2020-1-9 09:34

#include <stdio.h>
#include <sys/socket.h>
#include <unistd.h>

int main(void)
{
        int bufsize = 0;
        int nLen = 0;

        int tcpfd = socket(AF_INET, SOCK_STREAM, 0);
        nLen = sizeof(bufsize);
        getsockopt(tcpfd, SOL_SOCKET, SO_RCVBUF, &bufsize, &nLen);
        printf("TCP RecvBuf = %d\n", bufsize);
        nLen = sizeof(bufsize);
        getsockopt(tcpfd, SOL_SOCKET, SO_SNDBUF, &bufsize, &nLen);
        printf("TCP SendBuf = %d\n", bufsize);

        int udpfd = socket(AF_INET, SOCK_DGRAM, 0);
        nLen = sizeof(bufsize);
        getsockopt(udpfd, SOL_SOCKET, SO_RCVBUF, &bufsize, &nLen);
        printf("UDP RecvBuf = %d\n", bufsize);
        nLen = sizeof(bufsize);
        getsockopt(udpfd, SOL_SOCKET, SO_SNDBUF, &bufsize, &nLen);
        printf("UDP SendBuf = %d\n", bufsize);

        close(tcpfd);
        close(udpfd);
        return 0;
}

这是linux系统查看socket发送/接收缓冲区大小的代码,windows也差不多。
页: [1]
查看完整版本: win7系统级socket缓冲区有多大?