socket数据收发
socket读写
TCP协议是面向流的,read和write调用的返回值往往小于参数指定的字节数。对于read调用,如果接收缓冲区中有20字节,请求读100个字节,就会返回20。对于write调用,如果请求写100个字节,而发送缓冲区中只有20个字节的空闲位置,那么write会阻塞,直到把100个字节全部交给发送缓冲区才返回。但如果socket文件描述符中有O_NONBLOCK标志,则write不阻塞,直接返回20。
为避免这些情况干扰主程序逻辑,确保读写所请求的字节数,应包装read和write函数。
当设置socket为非阻塞模式时,要用select()或epoll()判断什么时候可正常写入或读出。
- write
sszie_t write(int fd, const void *buf, size_t count);
return:成功,返回写入的字节数;失败-1。
在网络程序中,当我们向socket写时有两种可能:
- write的返回值大于0,表示写了部分或者全部的数据。
- 返回值小于0,此时出现了错误。我们要根据错误类型来处理。如果错误为EINTR表示在写的时候出现了中断错误,应重试。如果为EPIPE表示网络连接出现了问题(对方已经关闭了连接,返回-1)。
- 此外还有可能socket为非阻塞(O_NONBLOCK),当缓冲区满时,立即返回0。(我的想法) ----错误想法,fd设置为非阻塞时,不能写立即返回-1,设置errno为EAGAIN或EWOULDBLOCK(man write ERRORS)。
- 返回0时,表示未写数据,继续写即可。
int my_write(int fd, void *buffer, int len){
int bytes_left;
int written_bytes;
char *ptr;
ptr = buffer;
bytes_left = len;
while(bytes_left > 0){
written_bytes = write(fd, ptr, bytes_left);
if(writte_bytes <= 0){ //出错了
if(errno == EINTR && written_bytes < 0) // 中断错误,继续写。
writen_bytes = 0;
else //其他错误,直接退出
return -1;
}
bytes_left -= writen_bytes;
ptr += written_bytes;
}
return len;
}
- read
ssize_t read(int fd, void *buf, size_t count);
return:成功,返回读取到的字节数;失败-1。
返回值为0,表示已经读到文件的结束;返回值小于0 表示出现了错误。如果错误为EINTR说明读是由中断引起的(继续读),如果是ECONNREST表示网络连接出了问题。
read()阻塞时,一直等,等于0表示文件结束或网络连接关闭;read()非阻塞,无数据可读时立即返回-1,errno为EAGAIN(若一直读,一直返回-1,errno为EAGAIN)。
int my_read(int fd,void *buffer,int length){
int bytes_left;
int bytes_read;
char *ptr;
bytes_left=length;
while(bytes_left>0){
bytes_read=read(fd,ptr,bytes_left);
if(bytes_read<0){
if(errno==EINTR) // 中断引起的,继续读
bytes_read=0;
else
return(-1); //其他原因,直接退出
}
else if(bytes_read==0) // 对方close连接(收到FIN包)
break;
bytes_left-=bytes_read;
ptr+=bytes_read;
}
return(length-bytes_left);
}
- recvfrom
int recvfrom(int sockfd, void *buf, int len, unsigned int flags, struct sockaddr * from, int *fromlen);
- sendto
int sendto(int sockfd, const void *msg, int len, unsigned int flags, struct sockaddr *to, int tolen);
注:如果对信息的来源不感兴趣,可以将from和fromlen设置为NULL。
socket数据收发的更多相关文章
- Silverlight Socket 实现收发信息
原文 http://www.cnblogs.com/ZetaChow/archive/2009/05/16/2237347.html 刚接触Silverlight的时候,除了其异步应用WCF.流媒体. ...
- java网络编程——多线程数据收发并行
基本介绍与思路 收发并行 前一篇博客中,完成了客户端与服务端的简单TCP交互,但这种交互是触发式的:客户端发送一条消息,服务端收到后再回送一条.没有做到收发并行.收发并行的字面意思很容易理解,即数据的 ...
- C# 实现的多线程异步Socket数据包接收器框架
转载自Csdn : http://blog.csdn.net/jubao_liang/article/details/4005438 几天前在博问中看到一个C# Socket问题,就想到笔者2004年 ...
- AS3: Socket 数据包 收 发
AS3.0中使用Socket使用tcp服务器协议,它是一种流协议,不停的将分片传输给客户端,P作为流,发包是不会整包到达的,而是源源不断的. 它不同于UDP服务器协议,UDP作为数据包协议,整包到达. ...
- 项目总结22:Java UDP Socket数据的发送和接收
项目总结22:Java UDP Socket数据的发送和接收 1-先上demo 客户端(发送数据) package com.hs.pretest.udp; import java.io.IOExcep ...
- FPGA的GTP(aurora 协议)高速串行接口数据收发(转)
reference:https://blog.csdn.net/qq_40261818/article/details/83039829 PG046-Aurora 8B/10B Logicore I ...
- STM32 使用Cubemx 建一个USB(HID)设备下位机,实现数据收发
这里我主要说一下如何做一个USB下位机,这里主要分3部分:1.建立工程:2.添加报文描述符:3.数据的传输.这里就不讲USB的理论知识了,有想要了解的自行百度一下就可以了. 建立工程:工程建立参考:h ...
- HAL UART DMA 数据收发
UART使用DMA进行数据收发,实现功能,串口2发送指令到上位机,上位机返回数据给串口2,串口2收到数据后由串口1进行转发,该功能为实验功能 1.UART与DMA通道进行绑定 void HAL_UAR ...
- 转载 STM32 使用Cubemx 建一个USB(HID)设备下位机,实现数据收发
STM32 使用Cubemx 建一个USB(HID)设备下位机,实现数据收发 本文转载自 https://www.cnblogs.com/xingboy/p/9913963.html 这里我主要说一 ...
随机推荐
- 使用增强for循环遍历集合的时候操作集合的问题?
// 遍历一个list public static void printList(List<String> list){ for (String string : list) { list ...
- 关于iOS Category实现添加属性及成员变量
iOS分类: 很多说法是只能添加方法,而不能添加成员变量或属性. 有些人可能知道,这种说法是不严谨的,并不是绝对不能添加变量. 解释如下: 我们知道在一个类中用@property声明属性,编译器会自动 ...
- HDUOJ1086You can Solve a Geometry Problem too
You can Solve a Geometry Problem too Time Limit: 2000/1000 MS (Java/Others) Memory Limit: 65536/3 ...
- Python使用chardet包自动检测编码
chardet:charset detection 一旦自动检测出编码,就可以解码了. 八种文件打开方式 w:一旦打开文件,文件内容就清空了 r:只读方式打开 a:追加方式打开 r+:先读后写 以上四 ...
- JavaScript 设计模式之代理模式
一.代理模式概念解读 1.代理模式概念文字解读 代理,顾名思义就是帮助别人做事,GOF对代理模式的定义如下: 代理模式(Proxy),为其他对象提供一种代理以控制对这个对象的访问.代理模式使得代理对象 ...
- Eclipse 选中变量高亮显示设置
- 基于 html5 geolocation来获取经纬度地址(copy)
geolocation来获取经纬度地址 以前如果要获取互联网用户所在地都是根据用户的IP地址来获取地理位置,这样获取到的数据和真实数据有很大的偏差.为了获取更加精确的位置,可以使用了html5的geo ...
- Android开发学习之SQLite数据存取浅析
一.SQLite的介绍 1.SQLite简介 SQLite是一款轻型的数据库,是遵守ACID的关联式数据库管理系统,它的设计目标是嵌入 式的,而且目前已经在很多嵌入式产品中使用了它,它占用资源非常的低 ...
- Linux GPIO子系统
一 概述 Linux内核中gpio是最简单,最常用的资源(和 interrupt ,dma,timer一样)驱动程序,应用程序都能够通过相应的接口使用gpio,gpio使用0-MAX_INT之间的整数 ...
- RHCE7 管理II-4计划将来的Linux任务
(1) at 一次性的计划任务 语法: # at [参数] [时间] at> 执行的指令 退出at命令 ctrl+d [root@localhost ~]# at now at> mkdi ...