简体   繁体   中英

Setting TCP_NODELAY without knowing file descriptor

I can set TCP_NODELAY while accept the new connection like the following :

fd = accept(listener, (struct sockaddr *)&sin, &slen);
if (fd < 0) {
    perror("accept");
    return;
}
if (fd > FD_SETSIZE) {
    perror("fd > FD_SETSIZE\n");
    return;
}
int onex = 1 ;
setsockopt(fd,IPPROTO_TCP,TCP_NODELAY,&onex,sizeof(onex));

and also can set TCP_NODELAY after connect to server :

bzero(&addr,sizeof(addr));
addr.sin_family = AF_INET;
addr.sin_port = htons(port_to_order);
addr.sin_addr.s_addr = inet_addr(ipaddr);
if(connect(iConnCenter,(struct sockaddr *)&addr,sizeof(addr)) < 0){
    printf(" to DBServer.exe socket to iConn error:== [%d]\n",port_to_order );
    return -1 ;
}
int onex = 1 ;
setsockopt(iConnCenter,IPPROTO_TCP,TCP_NODELAY,&onex,sizeof(onex));

I have a case that I can not have the fd of the connection , it is a library function call which have no fd information , the following is the sample :

TraderApi* pTrader = TraderApi::CreateTraderApi();
TraderSpi spi(pTrader) ;
pTrader->Init(g_frontaddr,&spi);

then use pTrader->ReqService(structA) to do send data , in this case , I won't have the chance to have the connection fd , so I can not set TCP_NODELAY .

I like to know in this case , how can I set TCP_NODELAY ?! Is there a config file or else I can set TCP_NODELAY for all connections happened in this application or in this Operation System ?!

The application is in box running RedHat 3.10.x86_64 .

Edit :

I have googled and found the source sample of list-open-fd.c at

https://github.com/ONsec-Lab/scripts/blob/master/list-open-fd.c

for( fd=0; fd<65535; fd++) {
   if( fstat( fd, &st) == -1) {
     continue;
   }

  switch (st.st_mode & S_IFMT) {
    case S_IFBLK:  printf("fd %d is block device\n", fd);            break;
    case S_IFCHR:  printf("fd %d is character device\n", fd);        break;
    case S_IFDIR:  printf("fd %d is directory\n", fd);               break;
    case S_IFIFO:  printf("fd %d is FIFO/pipe\n", fd);               break;
    case S_IFLNK:  printf("fd %d is symlink\n", fd);                 break;
    case S_IFREG:  printf("fd %d is regular file\n", fd);            break;
    case S_IFSOCK: printf("fd %d is socket\n", fd);                  break;
    default:       printf("fd %d is unknown?\n", fd);                break;
  }
} //for 

I think I can get the fd which pTrader->Init create by checking fd with mode = IFSOCK .

If TraderAPI is calling Linux socket API's, then you can intercept the calls with your own implementation that will set TCP_NODELAY after the socket is created by the underlying API. You would likely need to provide your intercepted calls via a shared library, and load it via LD_PRELOAD .

To call the real socket API, you could use dlopen on libc.so and dlsym the socket APIs you are intercepting and store the function pointers. Then invoke them when you need to call the real API.

The technical post webpages of this site follow the CC BY-SA 4.0 protocol. If you need to reprint, please indicate the site URL or the original address.Any question please contact:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM