一旦,我们建立好了tcp连接之后,我们就可以把得到的fd当作文件描述符来使用。

由此网络程序里最基本的函数就是read和write函数了。

写函数:

ssize_t write(int fd, const void*buf,size_t nbytes);

write函数将buf中的nbytes字节内容写入文件描述符fd.成功时返回写的字节数.失败时返回-1. 并设置errno变量. 在网络程序中,当我们向套接字文件描述符写时有两可能.

1)write的返回值大于0,表示写了部分或者是全部的数据. 这样我们用一个while循环来不停的写入,但是循环过程中的buf参数和nbyte参数得由我们来更新。

也就是说,网络写函数是不负责将全部数据写完之后在返回的。

2)返回的值小于0,此时出现了错误.我们要根据错误类型来处理. 如果错误为EINTR表示在写的时候出现了中断错误. 如果为EPIPE表示网络连接出现了问题(对方已经关闭了连接).

为了处理以上的情况,我们自己编写一个写函数来处理这几种情况.

int my_write(int fd,void *buffer,int length)
{
int bytes_left;
int written_bytes;
char *ptr;
ptr=buffer;
bytes_left=length;
while(bytes_left>0)
{ /* 开始写*/ written_bytes=write(fd,ptr,bytes_left); if(written_bytes<=0) /* 出错了*/ {        if(errno==EINTR) /* 中断错误 我们继续写*/ written_bytes=0; else             /* 其他错误 没有办法,只好撤退了*/ return(-1); } bytes_left-=written_bytes; ptr+=written_bytes;     /* 从剩下的地方继续写   */
}
return(0);
} 

读函数read

ssize_t read(int fd,void *buf,size_t nbyte)

read函数是负责从fd中读取内容.当读成功 时,read返回实际所读的字节数,如果返回的值是0 表示已经读到文件的结束了,小于0表示出现了错误.如果错误为EINTR说明读是由中断引起 的, 如果是ECONNREST表示网络连接出了问题. 和上面一样,我们也写一个自己的读函数.

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_read); if(bytes_read<0) { if(errno==EINTR) bytes_read=0; else return(-1); } else if(bytes_read==0) break; bytes_left-=bytes_read; ptr+=bytes_read;
}
return(length-bytes_left);
}

socket中read、write、send、recv函数的比较

建立好了TCP连接之后,我们就可以把得到的套接字当做文件描述符来使用,由此,想到了网络程序里面的基本的读写函数read和write函数。

Write函数

Ssize_t write(int fd,const void *buf,size_t nbytes);

Write函数将buf中的nbytes字节内容写入到文件描述符中,成功返回写的字节数,失败返回-1.并设置errno变量。在网络程序中,当我们向套接字文件描述舒服写数据时有两种可能:

1、write的返回值大于0,表示写了部分数据或者是全部的数据,这样用一个while循环不断的写入数据,但是循环过程中的buf参数和nbytes参数是我们自己来更新的,也就是说,网络编程中写函数是不负责将全部数据写完之后再返回的,说不定中途就返回了!

2、返回值小于0,此时出错了,需要根据错误类型进行相应的处理。

如果错误是EINTR表示在写的时候出现了中断错误,如果是EPIPE表示网络连接出现了问题。

Read函数

Ssize_t read(int fd,void *buf,size_t nbyte)

Read函数是负责从fd中读取内容,当读取成功时,read返回实际读取到的字节数,如果返回值是0,表示已经读取到文件的结束了,小于0表示是读取错误。

如果错误是EINTR表示在写的时候出现了中断错误,如果是EPIPE表示网络连接出现了问题。

有了上面的两个函数,我们就可以向客户端或者是服务器端进行数据传输了!比如我要传送一个结构体,可以使用下面的方法:

客户端向服务器:

Struct student stu;

Write(sock,(void *)&stu,sizeof(struct student));

服务器读:

Char buffer[sizeof(struct student)];

Struct *my_student;

Read(sock,(void *)buffer,sizeof(struct student));

My_student=(struct student)buffer;

在网络上传递数据时,我们一般把数据转换为char类型,接收的时候也是一样的的。没必要在网络上传递指针。

Recv函数和send函数

Recv函数和read函数提供了read和write函数一样的功能,不同的是他们提供了四个参数。

Int recv(int fd,void *buf,int len,int flags)

Int send(int fd,void *buf,int len,int flags)

前面的三个参数和read、write函数是一样的。第四个参数可以是0或者是一下组合:

MSG_DONTROUTE:不查找表

是send函数使用的标志,这个标志告诉IP,目的主机在本地网络上,没有必要查找表,这个标志一般用在网络诊断和路由程序里面。

MSG_OOB:接受或者发生带外数据

表示可以接收和发送带外数据。

MSG_PEEK:查看数据,并不从系统缓冲区移走数据

是recv函数使用的标志,表示只是从系统缓冲区中读取内容,而不清楚系统缓冲区的内容。这样在下次读取的时候,依然是一样的内容,一般在有过个进程读写数据的时候使用这个标志。

MSG_WAITALL:等待所有数据

是recv函数的使用标志,表示等到所有的信息到达时才返回,使用这个标志的时候,recv返回一直阻塞,直到指定的条件满足时,或者是发生了错误。

转载于:https://www.cnblogs.com/jiu0821/p/5833738.html

使用read write 读写socket相关推荐

  1. 图解 | 当我们在读写 Socket 时,我们究竟在读写什么?

    套接字socket是大多数程序员都非常熟悉的概念,它是计算机网络编程的基础,TCP/UDP收发消息都靠它.我们熟悉的web服务器底层依赖它,我们用到的MySQL关系数据库.Redis内存数据库底层依赖 ...

  2. 【动画】当我们在读写Socket时,我们究竟在读写什么?

    套接字socket是大多数程序员都非常熟悉的概念,它是计算机网络编程的基础,TCP/UDP收发消息都靠它.我们熟悉的web服务器底层依赖它,我们用到的MySQL关系数据库.Redis内存数据库底层依赖 ...

  3. 脑残式网络编程入门(二):我们在读写Socket时,究竟在读写什么?

    转载自 http://www.52im.net/thread-1732-1-1.html 1.引言 本文接上篇<脑残式网络编程入门(一):跟着动画来学TCP三次握手和四次挥手>,继续脑残式 ...

  4. eventlet并发读写socket出现Second simultaneous问题

    描述 celery+eventlet实现任务调用时出现RuntimeError: Second simultaneous read on fileno 14 detected. Unless you ...

  5. 深入理解阻塞socket和非阻塞socket

    什么是阻塞socket,什么是非阻塞socket.对于这个问题,我们要先弄清什么是阻塞/非阻塞.阻塞与非阻塞是对一个文件描述符指定的文件或设备的两种工作方式. 阻塞的意思是指,当试图对该文件描述符进行 ...

  6. 基于TCP协议的Socket通信,实现文件断点续传

    代码示例: 实现文件断点续传 先编写一个服务端和客户端都会用到的流解析类: StreamTool.java: public class StreamTool {public static void s ...

  7. python应用系列教程——python使用SocketServer实现网络服务器,socket实现客户端

    全栈工程师开发手册 (作者:栾鹏) python教程全解 python使用SocketServer实现网络服务器 SocketServer简化了网络服务器的编写.在进行socket创建时,使用Sock ...

  8. socket多进程编程

    socket多进程编程 一.服务器并发访问的问题 服务器按处理方式可以分为迭代服务器和并发服务器两类.平常用C写的简单Socket客户端服务器通信,服务器每次只能处理一个客户的请求,它实现简单但效率很 ...

  9. Linux网络编程——socket、bind、listen、accpet、connect、read和write

    Linux网络编程 基础理论 1.TCP/UDP/端口号 2.字节序 一.socket服务器与客户端的开发步骤 二.具体使用步骤 1.socket(创建连接协议) 2.bind(地址准备好) 3.li ...

最新文章

  1. Xcode7查看iphone真机的应用程序文件
  2. kayui进行添加_关于layui 实现点击按钮添加一行(方法渲染创建的table)
  3. 做这个AI项目面试通过率达95%
  4. 计算机控制基础知识,最新 分析计算机控制系统及其运算基础知识-精品
  5. 内网穿透工作笔记001---UDP通信_内网通信原理_P2P点对点通信原理
  6. C 语言学习:班级同学的博客地址列表
  7. hdfs MapTask类
  8. iOS 审核之 Performance - 2.5.2 被拒 dlopen(), dlsym(), respondsToSelector:, performSelector
  9. Rhinoceros技巧:有关曲线和曲面的分析
  10. 文本在线查重系统的设计与实现(毕业设计)
  11. quartz之动态定时器实现
  12. 地图比例尺与空间分辨率之间的关系_地图比例尺,分辨率,dpi之间的关系
  13. git 强制回滚到某个commit版本
  14. MongoDB快速入门学习
  15. 2、解读中台 -- 中台的作用
  16. PLC滑动平均值滤波(SMART 200梯形图篇)
  17. 魅族MX4安装Ubuntu Touch系统
  18. win10上运行emwin
  19. (附源码)springboot实验室自主预约系统 毕业设计111953
  20. 无锡新区新洲生活广场

热门文章

  1. 计算机网络知到马惜平答案,计算机网络实习用Dreamweaver搭建个人网站
  2. c语言解析sql语句_sql语句面试50题(Mysql版附解析)
  3. java人工洗牌窗口程序_求解,用JAVA写洗牌与发牌模拟程序
  4. mysql query browswer_MySQL数据库新特性之存储过程入门教程
  5. java 限制文本框长度_java中限制文本框输入长度的显示(转载)
  6. 三星 arm9 linux,基于arm9内核三星s3c2410平台下linux四键按键驱动程序
  7. apache 2.4 配置php,Apache2.4 PHP 配置
  8. oracle10gr2完全卸载,Oracle10gR2Streams删除所有配置
  9. 整数中内存中的保存方式:大端、小端
  10. Matlab实现 sift 特征匹配(代码源自网络)