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写时有两种可能:

  1. write的返回值大于0,表示写了部分或者全部的数据。
  2. 返回值小于0,此时出现了错误。我们要根据错误类型来处理。如果错误为EINTR表示在写的时候出现了中断错误,应重试。如果为EPIPE表示网络连接出现了问题(对方已经关闭了连接,返回-1)。
  3. 此外还有可能socket为非阻塞(O_NONBLOCK),当缓冲区满时,立即返回0。(我的想法) ----错误想法,fd设置为非阻塞时,不能写立即返回-1,设置errno为EAGAIN或EWOULDBLOCK(man write ERRORS)。
  4. 返回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数据收发的更多相关文章

  1. Silverlight Socket 实现收发信息

    原文 http://www.cnblogs.com/ZetaChow/archive/2009/05/16/2237347.html 刚接触Silverlight的时候,除了其异步应用WCF.流媒体. ...

  2. java网络编程——多线程数据收发并行

    基本介绍与思路 收发并行 前一篇博客中,完成了客户端与服务端的简单TCP交互,但这种交互是触发式的:客户端发送一条消息,服务端收到后再回送一条.没有做到收发并行.收发并行的字面意思很容易理解,即数据的 ...

  3. C# 实现的多线程异步Socket数据包接收器框架

    转载自Csdn : http://blog.csdn.net/jubao_liang/article/details/4005438 几天前在博问中看到一个C# Socket问题,就想到笔者2004年 ...

  4. AS3: Socket 数据包 收 发

    AS3.0中使用Socket使用tcp服务器协议,它是一种流协议,不停的将分片传输给客户端,P作为流,发包是不会整包到达的,而是源源不断的. 它不同于UDP服务器协议,UDP作为数据包协议,整包到达. ...

  5. 项目总结22:Java UDP Socket数据的发送和接收

    项目总结22:Java UDP Socket数据的发送和接收 1-先上demo 客户端(发送数据) package com.hs.pretest.udp; import java.io.IOExcep ...

  6. FPGA的GTP(aurora 协议)高速串行接口数据收发(转)

    reference:https://blog.csdn.net/qq_40261818/article/details/83039829 PG046-Aurora 8B/10B  Logicore I ...

  7. STM32 使用Cubemx 建一个USB(HID)设备下位机,实现数据收发

    这里我主要说一下如何做一个USB下位机,这里主要分3部分:1.建立工程:2.添加报文描述符:3.数据的传输.这里就不讲USB的理论知识了,有想要了解的自行百度一下就可以了. 建立工程:工程建立参考:h ...

  8. HAL UART DMA 数据收发

    UART使用DMA进行数据收发,实现功能,串口2发送指令到上位机,上位机返回数据给串口2,串口2收到数据后由串口1进行转发,该功能为实验功能 1.UART与DMA通道进行绑定 void HAL_UAR ...

  9. 转载 STM32 使用Cubemx 建一个USB(HID)设备下位机,实现数据收发

    STM32 使用Cubemx 建一个USB(HID)设备下位机,实现数据收发  本文转载自 https://www.cnblogs.com/xingboy/p/9913963.html 这里我主要说一 ...

随机推荐

  1. 转multicast vs broadcast

    转自:http://blog.csdn.net/bloghome/article/details/4682984 一.multicast概述:   多媒体应用集成了声音.图形.动画.文本以及视频,这种 ...

  2. ssh/scp 远程连接ssh非默认端口方法

    ssh -p port <username>@<IP>

  3. 具体解释java中的volatilekeyword

    一.为什么要有volatilekeyword 预计非常多java刚開始学习的人都被volatile这个keyword迷惑过.尽管网上有非常多讨论volatile的文章,但它们有的过于讲述底层原理,而没 ...

  4. Python 列表 insert() 方法

    描述 Python 列表 insert() 方法将指定对象插入到列表中的指定位置. 语法 insert() 方法语法: L.insert(index,obj) 参数 index -- 对象obj需要插 ...

  5. oracle序列sequence操作汇总(命令)--待续

    1.创建sequence 2.删除sequence 3.查询有哪些sequence select * from user_objects where object_type='SEQUENCE'; 4 ...

  6. php 第三方DB库NOTORM

    百度NOTORM找到该库的官网 :http://www.notorm.com/ 打开E:\AppServ\php7\php.ini 找到extension=php_pdo_mysql.dll 解开前面 ...

  7. 江南白衣 Java性能优化PPT

    会后江南白衣花费数日整理PPT,到1.4版本共66页,内容翔实且旁征博引,不断校正且力求做到极致的匠艺精神值得尊敬! 技术大牛飒然Hang如是说到: “技术大神中,除了陈皓就是白衣了,四十岁还能钻研. ...

  8. WPF绑定时要绑定属性,不要绑定字段

    如题(就是加get;set;),绑定属性不出东西,不知道为什么...

  9. 在向"带有自增字段的数据库表"中插入数据时,自定义"该自增字段"的数据

    在设计数据库表的时候,经常会使用自增主键或其他自增字段.比如: DB_UserGroups表中GroupID为该表主键,并为自增字段. 但在将某字段设置自增后,想在插入数据时,人为指定自增字段的数据内 ...

  10. Statistical Concepts and Market Returns

    Statistical Concepts and Market Returns Categories of statistics Descriptive statistics: used to sum ...