Linux网络编程之socket编程(五)-readline

前面学习了readn和writen封装函数的相关内容,接下来学习:read、write与recv、send的区别,readline实现,用readline实现回射客户/服务器以及getsockname、getpeername等一系列函数。

1.read、write与recv、send

(1)recv函数只能用于套接口I\O,而read函数可以用于任何I\O

(2)recv函数与read函数相比,多了一个flags选项。该选型可以指定接收的行为(常用的有MSG_OOBMSG_PEEK)。

(3)MSG_PEEK:可以接收缓冲区中的数据,但是并没有将数据从缓冲区中清除。下面封装一个recv_peek函数:

2.readline实现

(1)使用上面封装的recv_peek函数来实现readline功能——按行读取。即,读到\n为一条消息。
使用readline也可以解决粘包问题,ftp就是采用类似的机制。

(2)实现按行读取标准的做法是一个字符一个字符的读取,并判断该字符是否为\n。但是,这种做法效率较低。这里采用“偷窥”的方法

(3)使用recv_peek函数来实现readline:

1)首先调用recv_peek函数,来偷窥“接收”缓冲区中是否有\n。(recv_peek不清除缓冲区)
2)前一步偷窥到\n后,就可以利用readn函数将\n之前的数据(包括\n)读走。
3)若没有偷窥到\n字符,那么也可以断言recv_peek读到的这些数据也是包含在“发送数据”之内的,调用readn将其发送出去(同时清除了缓冲区)。然后,再进行下一次“偷窥”…

3.readline实现回射客户/服务器

echosrv.c

echocli.c

4.getsockname,getpeername

需要这两个函数的理由主要有:
(1)在一个没有调用bind的TCP客户上,connect成功返回后,getsockname用于返回由内核赋予该连接的本地IP地址和本地端口号。

(2)在以端口号0调用bind(告知内核去选择本地端口号)后,getsockname用于返回由内核赋予的本地端口号。

(3)getsockname可用于获取某个套接字的地址族。

(4)在一个以通配IP地址调用bind的TCP服务器上,与某个客户的连接一旦建立(accept成功返回),getsockname就可以用于返回由内核赋予该连接的本地IP地址。在这样的调用中,套接字描述符参数必须是已连接套接字的描述符,而不是监听套接字的描述符。

如上客户端示例,getsockname()函数用于获取一个套接字的名字。它用于一个已捆绑或已连接套接字s,本地地址将被返回。

发表评论

电子邮件地址不会被公开。 必填项已用*标注