分类 编程语言 下的文章

Linux下Socket编程遇到的问题和总结

1.向已关闭的fd写入数据的时候造成的程序退出解决办法

问题描述:
当服务器close一个连接时,若client端接着发数据。根据TCP协议的规定,会收到一个RST响应,client再往这个服务器发送数据时,系统会发出一个SIGPIPE信号给进程,告诉进程这个连接已经断开了,不要再写了。
又或者当一个进程向某个已经收到RST的socket执行写操作是,内核向该进程发送一个SIGPIPE信号。该信号的缺省学位是终止进程,因此进程必须捕获它以免不情愿的被终止。
我遇到的情况是客户端socket句柄已关闭,然后服务器像一个已关闭的客户端连接句柄中执行写操作,从而产生了SIGPIPE信号。
问题原因:
根据信号的默认处理规则SIGPIPE信号的默认执行动作是terminate(终止、退出),所以进程会退出。
系统里边定义了三种处理方法: 
    1)SIG_DFL     
    2)SIG_IGN     
    3)SIG_ERR     
根据信号的默认处理规则SIGPIPE信号的默认执行动作是terminate(终止、退出),所以进程会退出。若不想客户端退出,需要把 SIGPIPE默认执行动作屏蔽。
问题解决:
将SIGPIPE的默认处理方法屏蔽,我找到了两种方法:用signal(SIGCHLD,SIG_IGN)或者重载其处理方法。个人选了后者。两者区别在于signal设置的信号句柄只能起一次作用,信号被捕获一次后,信号句柄就会被还原成默认值了;sigaction设置的信号句柄,可以一直有效,值到你再次改变它的设置。具体代码如下:
struct sigaction action;
action.sa_handler = handle_pipe;
sigemptyset(&action.sa_mask);
action.sa_flags = 0;
sigaction(SIGPIPE, &action, NULL);
void handle_pipe(int sig)
{//不做任何处理即可}
在源文件中要添加signal.h头文件:#include <signal.h>

参考自:http://blog.sina.com.cn/s/blog_6f7c07a00101g7u3.html

2.read函数读取空数据并不是像accept函数那样执行无限挂起操作

当使用read函数读取套接字的时候,当数据已被取完,而客户端又没有发送数据的时候,read会挂起,但并不是永久的,有一个超时时间,超过以后就会返回0,也就是读取了0个字节,这个时候得特殊处理。

3.多线程接收客户端请求的时候不能用局部变量传递fd

由于Linux下创建线程传递的是参数指针,而不是参数本身,所以参数不是按值复制给函数的,如果直接将局部变量的地址传递给线程函数的话,可能那个值在主循环中的下一次循环里已经改变了,变成了下一个客户的fd,这个时候前一个子线程获取的fd就是改变后的fd,这会造成严重的问题。所以在创建线程之前,需要单独用malloc等函数分配一块内存空间,用于存放当前fd的拷贝,或者干脆一开始就使用分配的内存空间来存储accept返回的fd,将分配的内存空间的地址传递作为线程的参数,而该内存空间由各线程自己负责清理释放。

下载JAVA旧版本的方法

目前很多开发工具不支持最新的jdk1.7 ,所以给很多人造成了困难,而sun公司官网上又只显示了最新版的java下载地址。

我找了一会,发现有个页面是用来保存以往版本的:

http://java.sun.com/products/archive/

免登陆下载方法:

将下载地址中的otn替换为otn-pub

里面包含了所有版本的java 环境和开发包的下载地址。

MFC的EDIT控件多行显示的问题

    今天没事写个小程序,但竟然遇到各种各样的小问题,看来还是经验不足啊,虽然最后所有的小问题都经过 摸索+搜索 的方式解决了,但有些东西还是有必要写一下。

    其中一个重要的东西就是关于EDIT控件的多行显示问题,通常情况下,要让EDIT控件显示多行文本,只需要将其MultiLine属性设置为True就可以了,然后使用SetDlgItemText函数写入含有\n的文本就可以了,但是我为了让其有水平滚动条,于是将Horizontal Scroll设置为True,结果问题来了,我发现当我用SetDlgItemText函数写入含有\n的字符串的时候,它不换行了,我开始以为是BUG,结果折腾了半天,才发现如果将Horizontal Scroll设置为True,要想其换行,光靠\n不够了,还得加上\r,即是说\r\n一个回车符加一个换行符才行!不知道为什么微软会这么设定,用水平滚动条换行就得加回车符。。。

MFC的EDIT多行显示的问题