当您读取一个已关闭的TCP套接字时,您会收到一个常规错误,即它返回0表示EOF或-1,以及一个errno可以打印的错误代码perror.
但是,当您编写一个封闭的TCP套接字时,操作系统会发送SIGPIPE到您的应用程序,如果没有捕获,它将终止应用程序
为什么写封闭的TCP套接字比读取它更糟糕?
language-agnostic sockets network-programming network-protocols
我想知道静态成员变量通常是如何在C++等语言中实现的,如果它们的使用会影响实例化对象的大小.
我知道静态成员由该类的所有实例共享,但它是如何共享的?如果它影响对象大小,那么有10个静态变量会增加大于1的大小吗?
我问,因为我可以想到它可以实现的两种方式:
每个人都知道一个进程的经典模型,它监听套接字上的连接并分支新进程来处理每个新连接.通常的做法是父进程立即调用close新创建的套接字,减少句柄计数,以便只有子进程有新套接字的句柄.
我已经读过Linux中进程和线程之间的唯一区别是线程共享相同的内存.在这种情况下,我假设产生一个新的线程来处理一个新的连接也复制文件描述符,还需要'父'线程来关闭它的套接字副本?
作为STL容器的类成员的完成失败.
对作为STL容器的本地对象的完成工作正常.
例如,给定以下文件:
// foo.h
#include <string>
class foo {
public:
void set_str(const std::string &);
std::string get_str_reverse( void );
private:
std::string str;
};
// foo.cpp
#include "foo.h"
using std::string;
string
foo::get_str_reverse ( void )
{
string temp;
temp.assign(str);
reverse(temp.begin(), temp.end());
return temp;
} /* ----- end of method foo::get_str ----- */
void
foo::set_str ( const string &s )
{
str.assign(s);
} /* ----- end of method foo::set_str ----- */
Run Code Online (Sandbox Code Playgroud)
我使用以下方法为这两个文件生成了标签:
ctags -R --c++-kinds=+pl --fields=+iaS --extra=+q .
Run Code Online (Sandbox Code Playgroud)
当我输入temp.cpp时,我会string …
当我运行gcov foo.cpp时,它不仅为foo.cpp生成代码覆盖率报告,而且为foo.cpp使用的所有STL头生成.
有办法防止这种情况吗?它似乎忽略了标准的库标题<ctime>.
编辑
刚刚在gcc邮件列表上看过这篇文章:
我正在尝试测试一个被对等端优雅关闭的封闭套接字,而不会产生双重发送的延迟命中以引发SIGPIPE.
这里假设的一个假设是,在最后一次写入/发送之后,对等体在关闭后立即被对等体优雅地关闭.像过早关闭这样的实际错误将在代码中的其他地方处理.
如果套接字仍然打开,那么将有0个或更多字节数据,我实际上并不想从套接字缓冲区中取出.
我以为我可以打电话int ret = recv(sockfd, buf, 1, MSG_DONTWAIT | MSG_PEEK);来确定插座是否仍然连接.如果它的连接,但有一个在缓冲区中没有数据,我会得到的回报-1与errno == EAGAIN和返回的sockfd重用.如果它被对等方优雅地关闭,我将获得ret == 0并打开一个新连接.
我测试了这个,它似乎工作.但是,我怀疑在我收集数据的最后一位和同伴FIN到达时之间有一个小窗口,我可以EAGAIN从测试中得到假阳性recv.
这会咬我,还是有更好的方法呢?
在" Perl最佳实践 "中,AUTOLOAD部分的第一行是:
不要使用AUTOLOAD
然而,他描述的所有案例都涉及OO或模块.
我有一个独立的脚本,其中一些命令行开关控制定义特定函数的哪个版本.现在我知道我可以采取条件和描述并将其裸体放在我的文件顶部之前,但我觉得将它们放在文件末尾的AUTOLOAD中更方便,更清晰.
这是不好的做法/风格吗?如果你这么认为,为什么还有另一种方法呢?
按照布莱恩的要求
我基本上是用它来根据命令行开关进行条件编译.
我不介意一些建设性的批评.
sub AUTOLOAD {
our $AUTOLOAD;
(my $method = $AUTOLOAD) =~ s/.*:://s; # remove package name
if ($method eq 'tcpdump' && $tcpdump) {
eval q(
sub tcpdump {
my $msg = shift;
warn gf_time()." Thread ".threads->tid().": $msg\n";
}
);
} elsif ($method eq 'loginfo' && $debug) {
eval q(
sub loginfo {
my $msg = shift;
$msg =~ s/$CRLF/\n/g;
print gf_time()." Thread ".threads->tid().": $msg\n";
}
);
} elsif ($method eq 'build_get') …Run Code Online (Sandbox Code Playgroud) 我的理解是,在make执行时,它会在内部生成一个DAG来表示项目中的所有依赖项.有没有办法获得DAG并绘制图表,比如使用像graphviz这样的东西?
我在Ubuntu 8.04上使用gnu make.
编辑
我只是碰到这些工具被称为跑mamdag和mamdot.他们应该同时使用nmake和gnu make,但我似乎无法找到让gnu make吐出mam文件的选项.
它可以在这里下载 - 这些包:
INIT
ast-base
ast-gpl
刚刚在AT&T的Glenn Fowler发现了这篇文章,描述了MAM语言和mamdot工具.
看起来你必须修补gnu make才能工作,虽然我还不是100%肯定.
也许有另一种方式?
如何获取POSIX strerror_r而不是GNU版本?
我正在使用glibc 2.7版(基于其中的内容)在Ubuntu 8.04上使用g ++进行编译.
编辑
在上面的手册页中,它说:
glibc的功能测试宏要求(参见feature_test_macros(7)):
The XSI-compliant version of strerror_r() is provided if:
(_POSIX_C_SOURCE >= 200112L || _XOPEN_SOURCE >= 600) && ! _GNU_SOURCE
Otherwise, the GNU-specific version is provided.
Run Code Online (Sandbox Code Playgroud)
If no feature test macros are explicitly defined, then the following feature
test macros are defined by default: _BSD_SOURCE, _SVID_SOURCE, _POSIX_SOURCE,
and _POSIX_C_SOURCE=200809L (200112L in glibc versions before 2.10; 199506L in
glibc versions before 2.4; 199309L in glibc versions before 2.1).
Run Code Online (Sandbox Code Playgroud)
所以我应该得到POSIX版本,但我得到的是GNU版本.
根据C FAQ,基本上有3种用于在C中"内联"代码的实用方法:
#define MACRO(arg1, arg2) do { \
/* declarations */ \
stmt1; \
stmt2; \
/* ... */ \
} while(0) /* (no trailing ; ) */
Run Code Online (Sandbox Code Playgroud)
要么
#define FUNC(arg1, arg2) (expr1, expr2, expr3)
Run Code Online (Sandbox Code Playgroud)
为了澄清这一点,参数在表达式中使用,逗号运算符返回最后一个表达式的值.
要么
使用inline支持作为gcc扩展和c99标准的声明.
该do { ... } while (0)方法在Linux内核中被广泛使用,但是我还没有经常遇到其他两种方法.
我指的是多语句"函数",而不是像MAX或MIN这样的单语句.
每种方法的优点和缺点是什么,为什么在各种情况下你会选择一种方法呢?