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 这里我主要说一 ...
随机推荐
- Swift3 获取版本号,比较版本大小
Swift获取应用版本号:version 1.获取本地版本号 /// 获取本地版本号 func getLocalVersion() -> String { var localVersion:St ...
- NYOJ-------笨蛋难题四
笨蛋难题四 时间限制:1000 ms | 内存限制:65535 KB 难度:3 描述 这些日子笨蛋一直研究股票,经过调研,终于发现xxx公司股票规律,更可喜的是 笨蛋推算出这 ...
- Oracle实例
ORA-12505 Listener refused the connection with following error:ORA-12505,TNS:listener 确定这是连接数据库的SID错 ...
- supervisor+gunicorn部署python web项目
有了Nginx,对于Tomcat没有必要详细了解. 有了supervisor,再也没有必要把一个程序设置成服务.驻留进程,supervisor真是一个相见恨晚的好工具. 在Tomcat中,所有的web ...
- 基于node.js的web框架express
1.安装node.js方法: window :https://nodejs.org/en/ linux:http://www.runoob.com/nodejs/nodejs-install-setu ...
- Spring3 MVC请求参数获取的几种方法[转]
Spring3 MVC请求参数获取的几种方法 Spring3 MVC请求参数获取的几种方法 一. 通过@PathVariabl获取路径中的参数 @RequestMapping(value=& ...
- 跳出框架iframe的操作语句
常用的iframe操作语句 ① 本页面跳转语句: "window.location.href" 或者 "location.href" ② 上一层页面跳转 ...
- HTTP请求流程(二)----Telnet模拟HTTP请求
http://www.cnblogs.com/stg609/archive/2008/07/06/1237000.html 上一部分"流程简介", 我们大致了解了下HTTP请求的流 ...
- react 事件绑定的2种常用方式
方式一:传统 import React, { Component } from 'react'; class App extends Component { handleSubmit (e, args ...
- 使用Spring boot开发RestFul 风格项目PUT/DELETE方法不起作用
在使用Spring boot 开发restful 风格的项目,put.delete方法不起作用,解决办法. 实体类Student @Data public class Student { privat ...