[英]Setting TCP_NODELAY without knowing file descriptor
I can set TCP_NODELAY while accept the new connection like the following : 我可以在接受新连接的同时设置TCP_NODELAY,如下所示:
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 : 并且还可以在连接到服务器后设置TCP_NODELAY:
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 : 我遇到无法连接fd的情况,这是一个没有fd信息的库函数调用,以下是示例:
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 . 然后使用pTrader-> ReqService(structA)发送数据,在这种情况下,我将没有机会建立连接fd,因此无法设置TCP_NODELAY。
I like to know in this case , how can I set TCP_NODELAY ?! 我想知道在这种情况下,如何设置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 ?! 是否有配置文件,否则我可以为该应用程序或此操作系统中发生的所有连接设置TCP_NODELAY吗?
The application is in box running RedHat 3.10.x86_64 . 该应用程序在运行RedHat 3.10.x86_64的框中。
Edit : 编辑:
I have googled and found the source sample of list-open-fd.c at 我已经在google上搜索并找到了list-open-fd.c的源示例。
https://github.com/ONsec-Lab/scripts/blob/master/list-open-fd.c 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 . 我想我可以通过用mode = IFSOCK检查fd来获得pTrader-> Init创建的fd。
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. 如果TraderAPI
正在调用Linux套接字API,那么您可以使用自己的实现拦截调用,该实现将在基础API创建套接字之后设置TCP_NODELAY
。 You would likely need to provide your intercepted calls via a shared library, and load it via LD_PRELOAD
. 您可能需要通过共享库提供被拦截的呼叫,并通过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. 要调用真正的套接字API,可以在libc.so
上使用dlopen
,并在要拦截的套接字API上使用dlsym
并存储函数指针。 Then invoke them when you need to call the real API. 然后在需要调用真实API时调用它们。
声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.