我在理解Linux中套接字的工作方面遇到了一些问题.
setsockopt(sockfd, SOL_SOCKET, SO_SNDTIMEO, &timeout, sizeof(int));
write = write(sockfd, buf, len);
Run Code Online (Sandbox Code Playgroud)
在上面的代码中,写入被缓冲,发送超时没有任何意义(当用户空间缓冲区被复制到内核缓冲区时,写入系统调用将立即返回).发送缓冲区大小是更重要的参数,但发送超时似乎没有什么值得的.但我当然错了,因为我已经看到了很多使用SO_SNDTIMEO的代码.假设接收器非常慢,用户空间代码如何使用SO_SNDTIMEO超时?
我是socket编程的新手
我看到了一个ICMP请求程序,因为他们习惯setsockopt了socket
int on = 1;
setsockopt(s, IPPROTO_IP, IP_HDRINCL, &on, sizeof(on))
Run Code Online (Sandbox Code Playgroud)
但即使我不使用此语句,程序也能正常运行.为什么提到内核这个套接字包括IP结构如此重要?
我继承了一些调用的TCP代码:
bind(tcpSocket, (struct sockaddr*)&server_addr, sizeof(server_addr));
Run Code Online (Sandbox Code Playgroud)
在致电之前
setsockopt(tcpSocket, SOL_SOCKET, SO_REUSEADDR, &yes, sizeof(int));
Run Code Online (Sandbox Code Playgroud)
毫不奇怪,这导致了消息:"地址已在使用中".只需交换调用顺序即可解决问题.
这提出了一个问题:一般来说,是否应该setsockopt()在致电前拨打电话bind()?在打电话之前connect()?
我得到了以下链接:getsockopt() 中的 SOL_SOCKET
但这对我来说真的很困惑。一个回答说SOL_SOCKET是socket层的意思。什么是套接字层?该参数还有其他可用选项吗?
如果我们传递SOL_SOCKET参数会发生什么,它SOL代表什么?
我正在使用 UNIX。
我在 Centos 中使用以下代码将原始套接字缓冲区大小更改为 400 KB,但是在将缓冲区大小设置为 256 KB 时得到了相同的结果。哪里不对了?或者这是套接字层的限制?内核版本为 2.6.34。谢谢!
int rawsock;
socklen_t socklen;
int optval;
int bufsize = 400 * 1024;
rawsock = socket(PF_PACKET, SOCK_RAW, htons(ETH_P_ALL));
if (rawsock < 0) {
my_log(LOG_ERR, "error creating raw socket");
return rawsock;
}
optval = 0;
socklen = 4;
err = getsockopt(rawsock, SOL_SOCKET, SO_RCVBUF, &optval, &socklen);
bail_error(err);
my_log("socket RX original buffer size = %d", optval);
optval = 0;
socklen = 4;
err = getsockopt(rawsock, SOL_SOCKET, SO_SNDBUF, &optval, &socklen);
bail_error(err);
my_log("socket TX original buffer size …Run Code Online (Sandbox Code Playgroud) int n = 0;
if ( 0 != getsockopt(iSockFd,SOL_SOCKET,SO_RCVBUF, &n, sizeof(n)))
{
printf("Get socket option failed, errno: %d\n",errno);
}
else
{
printf("Current socket buff len = %d\n", n);
}
n = 225280;
if(0 != setsockopt(iSockFd, SOL_SOCKET, SO_RCVBUF, (const void *)&n, sizeof(n)))
{
printf("setsock err errno %d\n", errno);
}
else
{
printf("setsock opt success\n");
}
n = 0;
if ( 0 != getsockopt(iSockFd,SOL_SOCKET,SO_RCVBUF, &n, sizeof(n)))
{
printf("Get socket option failed, errno: %d\n",errno);
}
else
{
printf("After setting socket buff len = …Run Code Online (Sandbox Code Playgroud) 引用此在线内核文档
- SO_TIMESTAMPING 在接收、传输或两者上生成时间戳。支持多个时间戳源,包括硬件。支持为流套接字生成时间戳。
Linux 支持 TCP 时间戳,我尝试编写一些演示代码来获取 TCP 数据包的任何时间戳。
服务器端代码如下:
//Bind
if( bind(socket_desc,(struct sockaddr *)&server , sizeof(server)) < 0)
{
perror("bind failed. Error");
return 1;
}
puts("bind done");
//Listen
listen(socket_desc , 3);
//Accept and incoming connection
puts("Waiting for incoming connections...");
int c = sizeof(struct sockaddr_in);
client_sock = accept(socket_desc, (struct sockaddr *)&client, (socklen_t*)&c);
if (client_sock < 0)
{
perror("accept failed");
return 1;
}
// Note: I am trying to get software timestamp only here..
int oval = SOF_TIMESTAMPING_RX_SOFTWARE …Run Code Online (Sandbox Code Playgroud) 发送UDP多播时,您可以使用IP_MULTICAST_TTL设置TTL.但否则你会用IP_TTL.为什么这两种不同的选择在setsockopt()和getsockopt()?是否有任何情况下单独设置它们是否有意义?
在我看来,他们最终在IP头中设置了相同的值.
我的UDP套接字是bind()端口53(DNS).UDP是否具有TIME_WAIT状态或SO_REUSEADDR在UDP套接字上使用无意义?
当使用SO_RECVBUF调用setsockopt时,然后转向并使用SO_RECVBUF调用getsockopt,它似乎告诉我它将缓冲区大小设置为我要求它设置的两倍.有人知道为什么会这样吗?
有问题的代码:
https://gist.github.com/rdp/8443238
输出:
setting it as 2222
[udp @ 0x1a72ec0] end receive buffer size reported is 4444
Run Code Online (Sandbox Code Playgroud)
仅在linux中,在其他操作系统上似乎将其报告为我设置的值.谢谢.