macOS下调用setsockopt设置TCP_MAXSEG失败的问题咨询
macOS下调用setsockopt设置TCP_MAXSEG失败的问题咨询
嘿,这个坑我之前在macOS上踩过!你碰到的问题其实是BSD系系统(包括macOS)和Linux在TCP_MAXSEG选项设置时机上的差异导致的。
先给你点明核心原因:macOS不允许在监听套接字(就是你代码里刚创建的lsock)上设置TCP_MAXSEG,这个选项只能作用在已经建立连接的套接字上——也就是accept()函数返回的那个用于和客户端通信的套接字。
你看你现在的代码,刚调用socket()创建了监听socket就去设置MSS,这在Linux上是可行的(Linux允许在监听套接字设置,后续新连接会继承这个配置),但macOS的TCP栈不支持这个操作,所以直接返回EINVAL,也就是你看到的"Invalid argument"错误。
那怎么修正呢?给你个示例代码参考:
int lsock = socket(AF_INET, SOCK_STREAM, 0); if (lsock == -1) { perror("socket"); return 1; } // 先完成bind和listen的操作 struct sockaddr_in serv_addr = {0}; serv_addr.sin_family = AF_INET; serv_addr.sin_port = htons(8080); serv_addr.sin_addr.s_addr = INADDR_ANY; if (bind(lsock, (struct sockaddr*)&serv_addr, sizeof(serv_addr)) == -1) { perror("bind"); close(lsock); return 1; } if (listen(lsock, 5) == -1) { perror("listen"); close(lsock); return 1; } // 等待客户端连接,拿到已连接的套接字 struct sockaddr_in client_addr; socklen_t client_len = sizeof(client_addr); int connfd = accept(lsock, (struct sockaddr*)&client_addr, &client_len); if (connfd == -1) { perror("accept"); close(lsock); return 1; } // 现在对已连接的connfd设置TCP_MAXSEG int mss = 576; if (setsockopt(connfd, IPPROTO_TCP, TCP_MAXSEG, &mss, sizeof(mss)) != 0) { perror("setsockopt on connfd"); close(connfd); close(lsock); return 1; }
另外再补充两个细节:
- 你设置的MSS值576是符合要求的,macOS的TCP_MINMSS默认是536,只要不小于这个值就没问题;
- 如果想让所有新连接都使用这个MSS,macOS上没有像Linux那样的监听套接字继承机制,只能在每次
accept()之后单独对新的连接套接字设置。
内容来源于stack exchange
相关产品推荐
相关产品推荐

