Linux网络编程中的几组类似功能的区别

1.bzero与memset

char buff[1024];

memset(buff,0,sizeof(buff));bzero(buff, sizeof(buff));

struct sockaddr_in addr

memset(&addr, 0, sizeof(addr));

bzero(buff, sizeof(buff));

参考《UNIX网络编程 卷1:套接字联网API 第3版》1.2的解释:bzero不是ANSI C函数,起源于Berkeley网络编程代码,但是本书使用它却不用ANSI C的memset函数,因为bzero(带2个参数)比memset(带3个参数)更好记。因为原书第一版使用memset有些地方互换了第二个和第三个参数,因为类型一样,所以调用正常,不过没做任何事,因为待初始化的字节数被制定为0.程序之所以工作是因为只有少数套接字函数要求网际套接字地址结构的最后8个字节置0。


2.read和write与recv和send

参考《用TCP/IP进行网际互联 第3卷》:5.7.9  如同大多数unix系统,在Linux中,程序员可以用read代替recv,用write代替send。对TCP和UDP套接字来时候,read具有和recv一样的语义,write具有和send一样的语义。Read和write和主要优点是程序员对它们已经很熟悉;而send和recv的主要优点是它们在程序中标记明显

send、recv前面的三个参数和read、write函数是一样的。
第四个参数可以是0或者是以下组合:
MSG_DONTROUTE:不查找表
是send函数使用的标志,这个标志告诉IP,目的主机在本地网络上,没有必要查找表,这个标志一般用在网络诊断和路由程序里面。
MSG_OOB:接受或者发生带外数据
表示可以接收和发送带外数据。
MSG_PEEK:查看数据,并不从系统缓冲区移走数据
是recv函数使用的标志,表示只是从系统缓冲区中读取内容,而不清楚系统缓冲区的内容。这样在下次读取的时候,依然是一样的内容,一般在有过个进程读写数据的时候使用这个标志。
MSG_WAITALL:等待所有数据
是recv函数的使用标志,表示等到所有的信息到达时才返回,使用这个标志的时候,recv返回一直阻塞,直到指定的条件满足时,或者是发生了错误。
即read、write相当于send、recv的最后一个参数用0代替。

1、read 与 recv 区别

read 原则

        数据在不超过指定的长度的时候有多少读多少,没有数据则会一直等待所以一般情况下:我们读取数据都需要采用循环读的方式读取数据,因为一次read 完毕不能保证读到我们需要长度的数据,read 完一次需要判断读到的数据长度再决定是否还需要再次读取。

recv 原则
        recv 中有一个MSG_WAITALL 的参数:
                recv(sockfd, buff, buff_size, MSG_WAITALL),
        正常情况下recv 是会等待直到读取到buff_size 长度的数据,但是这里的WAITALL 也只是尽量读全,在有中断的情况下recv 还是可能会被打断,造成没有读完指定的buff_size的长度。所以即使是采用recv + WAITALL 参数还是要考虑是否需要循环读取的问题,在实验中对于多数情况下recv (使用了MSG_WAITALL)还是可以读完buff_size,
        所以相应的性能会比直接read 进行循环读要好一些。
 2、read 与 recv函数调用
        read(sockfd, buff, buff_size)
        write(sockfd, buff, buff_size)

        recv(sockfd, buff, buff_size,MSG_WAITALL); //阻塞模式接收
        send(scokfd, buff, buff_size,MSG_WAITALL); //阻塞模式发送

        recv(sockfd, buff, buff_size,MSG_DONTWAIT); //非阻塞模式接收
        send(scokfd, buff, buff_size,MSG_DONTWAIT); //非阻塞模式发送

        recv(sockfd, buff, buff_size,0);
        send(scokfd, buff, buff_size,0);
 3、socket编程经验
        1)尽量使用recv(,,MSG_WAITALL),read必须配合while使用,否则数据量大(240*384)时数据读不完
        2)编程时写入的数据必须尽快读出,否则后面的数据将无法继续写入
        3)最佳搭配如下:
                nbytes = recv(sockfd, buff, buff_size,MSG_WAITALL);
                nbytes = send(scokfd, buff, buff_size,MSG_WAITALL);


3.close与shutdown

int shutdown(int sockfd,int howto)
TCP连接是双向的(是可读写的),当我们使用close时,会把读写通道都关闭,有时侯我们希望只关闭一个方向,这个时候我们可以使用shutdown.针对不同的howto,系统回采取不同的关闭方式.
howto=0这个时候系统会关闭读通道.但是可以继续往接字描述符写.
howto=1关闭写通道,和上面相反,着时候就只可以读了.
howto=2关闭读写通道,和close一样 在多进程程序里面,如果有几个子进程共享一个套接字时,如果我们使用shutdown, 那么所有的子进程都不能够操作了,这个时候我们只能够使用close来关闭子进程的套接字描述符.


4.exit与return

exit()
是一个函数,结束一个进程,它将删除进程使用的内存空间,同时把错误信息返回父进程,在父进程中wait系统调用将接受到此返回信息。
return返回函数值,是关键字


参考:http://blog.163.com/like12@126/blog/static/63023403201291983117551/http://no001.blog.51cto.com/1142339/493619

你可能感兴趣的:(Linux网络编程中的几组类似功能的区别)