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. HDUOJ-----(1072)Nightmare(bfs)

    Nightmare Time Limit: 2000/1000 MS (Java/Others)    Memory Limit: 65536/32768 K (Java/Others) Total ...

  2. Foundations of Machine Learning: The PAC Learning Framework(2)

    Foundations of Machine Learning: The PAC Learning Framework(2) (一)假设集有限在一致性下的学习界. 在上一篇文章中我们介绍了PAC-le ...

  3. 【LeetCode】22. Generate Parentheses (2 solutions)

    Generate Parentheses Given n pairs of parentheses, write a function to generate all combinations of ...

  4. 【LeetCode】164. Maximum Gap (2 solutions)

    Maximum Gap Given an unsorted array, find the maximum difference between the successive elements in ...

  5. PHP5.4新特性

    PHP5.4 此次更新的关键新特性,包括:新增traits,更精简的Array数组语法,供测试使用的内建webserver,可以闭包使用的$this指针,实例化类成员访问, PHP 5.4.0 性能大 ...

  6. asp.net 在线解压缩文件类

    using System; using System.Collections.Generic; using System.Text; using System.IO; using Microsoft. ...

  7. GL_子模组过账至总账通过SLA修改会计方法改变科目(案列)

    2014-06-02 BaoXinjian

  8. PLSQL_标准游标类型的解析(概念)

    2014-06-02 Created By BaoXinjian

  9. Linux内核中锁机制之内存屏障、读写自旋锁及顺序锁

    在上一篇博文中笔者讨论了关于原子操作和自旋锁的相关内容,本篇博文将继续锁机制的讨论,包括内存屏障.读写自旋锁以及顺序锁的相关内容.下面首先讨论内存屏障的相关内容. 三.内存屏障 不知读者是是否记得在笔 ...

  10. ASP.NET Helper