Skip to content

Instantly share code, notes, and snippets.

@gregorycollins
Created October 16, 2012 16:57
Show Gist options
  • Save gregorycollins/3900556 to your computer and use it in GitHub Desktop.
Save gregorycollins/3900556 to your computer and use it in GitHub Desktop.
Is TCP_NODELAY inherited from listening sockets on your platform?
#include <errno.h>
#include <fcntl.h>
#include <netdb.h>
#include <netinet/in.h>
#include <netinet/tcp.h>
#include <stdlib.h>
#include <stdio.h>
#include <strings.h>
#include <sys/socket.h>
#include <sys/types.h>
#include <unistd.h>
int main() {
const int portnumber = 9233;
int lsock = 0;
if ((lsock = socket(AF_INET, SOCK_STREAM, IPPROTO_IP)) < 0) {
close(lsock);
exit(EXIT_FAILURE);
}
struct hostent* server = gethostbyname("127.0.0.1");
if (server == NULL) {
perror("gethostbyname");
exit(EXIT_FAILURE);
}
int nodelay_flag = 1;
setsockopt(lsock, IPPROTO_TCP, TCP_NODELAY, (void*) &nodelay_flag, sizeof(int));
int flags = fcntl(lsock, F_GETFL, 0);
fcntl(lsock, F_SETFL, flags | O_NONBLOCK);
struct sockaddr_in addr;
bzero(&addr, sizeof(struct sockaddr_in));
addr.sin_family = AF_INET;
addr.sin_port = htons(portnumber);
bcopy((char *)server->h_addr,
(char *)&addr.sin_addr.s_addr,
server->h_length);
if (bind(lsock, (struct sockaddr *) &addr, sizeof(struct sockaddr_in)) < 0) {
perror("bind");
exit(EXIT_FAILURE);
}
printf("Listening\n");
listen(lsock, 1);
sleep(1);
printf("Connecting\n");
int fd = 0;
if ((fd = socket(AF_INET, SOCK_STREAM, IPPROTO_IP)) < 0) {
perror("socket");
exit(EXIT_FAILURE);
}
int err_code = 0;
connect(fd, (struct sockaddr*) &addr, sizeof(struct sockaddr_in));
sleep(1);
printf("Accepting\n");
int sfd = accept(lsock, NULL, NULL);
if (sfd < 0) {
perror("accept");
exit(1);
}
socklen_t dummy;
nodelay_flag = -100;
getsockopt(sfd, IPPROTO_TCP, TCP_NODELAY, (void*) &nodelay_flag, &dummy);
printf("TCP_NODELAY on inherited socket is %d.\n", nodelay_flag);
flags = fcntl(sfd, F_GETFL, 0);
printf("O_NONBLOCK on inherited socket is %d.\n",
((flags & O_NONBLOCK) == 0));
return 0;
}
@mortehu
Copy link

mortehu commented Nov 26, 2015

Suggested change:

nodelay_flag = -100;
socklen_t dummy = sizeof(nodelay_flag);

For getsockopt(), optlen is a value-result argument, initially containing the size of the buffer pointed to by optval, and modified on return to indicate the actual size of the value returned.

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment