`
unsoundboy
  • 浏览: 63311 次
  • 性别: Icon_minigender_1
  • 来自: 武汉
社区版块
存档分类
最新评论

Linux网络编程--4. 完整的读写函数

阅读更多
Linux网络编程--4. 完整的读写函数
http://linuxc.51.net 作者:hoyt (2001-05-08 11:20:52)

一旦我们建立了连接,我们的下一步就是进行通信了.在Linux下面把我们前面建立的通道 看成是文件描述符,这样服务器端和客户端进行通信时候,只要往文件描述符里面读写东西了. 就象我们往文件读写一样. 


4.1 写函数write 

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

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

1)write的返回值大于0,表示写了部分或者是全部的数据. 

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);
}

4.2 读函数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);
}

4.3 数据的传递 
有了上面的两个函数,我们就可以向客户端或者是服务端传递数据了.比如我们要传递一个结构.可以使用如下方式 

 /*  客户端向服务端写 */

 struct my_struct my_struct_client;
 write(fd,(void *)&my_struct_client,sizeof(struct my_struct);

 /* 服务端的读*/ 
 char buffer[sizeof(struct my_struct)];
 struct *my_struct_server;
 read(fd,(void *)buffer,sizeof(struct my_struct)); 
 my_struct_server=(struct my_struct *)buffer;    

在网络上传递数据时我们一般都是把数据转化为char类型的数据传递.接收的时候也是一样的 注意的是我们没有必要在网络上传递指针(因为传递指针是没有任何意义的,我们必须传递指针所指向的内容) 
分享到:
评论

相关推荐

    Linux网络编程-网络基础-socket编程-高并发服务器.pdf

    【Linux网络编程-网络基础-socket编程-高并发服务器】 在深入探讨Linux下的网络编程之前,我们首先要理解网络通信的基础概念——协议。协议是数据传输和解释的规则,它确保了不同设备之间的通信能顺利进行。例如,...

    Linux程序设计-网络编程-第9章.ppt

    在Linux系统中,Socket类似于文件描述符,可以用于读写数据,且Socket接口定义了一系列函数,如`socket()`、`bind()`、`connect()`、`listen()`和`accept()`等,以支持TCP/IP网络上的应用程序开发。Socket分为两种...

    node-v0.10.0-linux-arm-pi.tar.gz

    4. **异步编程**:Node.js强调异步编程,避免了多线程带来的复杂性和开销,适合处理I/O密集型任务。 5. **文件系统API**:内置的fs模块提供了对文件系统进行读写操作的接口。 6. **网络编程**:Node.js有强大的...

    qt-x11-free-3.3.4.tar.gz

    **4. 开发环境搭建** - 配置环境变量:确保PATH包含Qt的bin目录,以便在命令行中使用Qt工具。 - IDE集成:可以使用Qt Creator作为集成开发环境,它内建了Qt的开发工具和调试器,方便编写和测试Qt应用。 - 创建项目:...

    netcdf-fortran-4.4.2.tar.gz

    在本例中,我们关注的是 `netcdf-fortran-4.4.2.tar.gz` 文件,它是一个针对 Fortran 编程语言的 NetCDF 库的版本4.4.2,特别适用于64位Linux系统,虽然32位系统的兼容性未明确提及。 **Fortran**: Fortran 是一种...

    libevent-2.0.15-stable.tar.gz

    《深入理解libevent-2.0.15-stable:事件驱动...它通过抽象出事件模型,简化了网络编程的复杂性,让开发者能够专注于业务逻辑,而不是底层的系统调用。在开发基于事件驱动的网络应用时,libevent是一个值得信赖的选择。

    muduo-0.9.1-beta.tar.gz

    muduo由知名C++开发者陈硕开发,它以事件驱动的方式处理网络I/O,采用了单线程非阻塞I/O模型,利用Linux的epoll机制实现高效的数据读写。muduo库的核心特点是线程安全和轻量级,它包含网络编程的基础组件,如网络套...

    Linux程序设计-网络编程-第9章.rar

    在Linux系统中,网络编程是实现跨机器通信的关键技术,广泛应用于服务器开发、客户端应用以及分布式系统中。本章重点讨论的是"Linux程序设计-网络编程"中的第九章内容,虽然具体的章节标题未给出,但我们可以推测这...

    Linux网络编程-文字版.pdf

    在Linux网络编程中,套接字API包括创建套接字(socket())、绑定地址(bind())、监听连接(listen())、接受连接(accept())、发起连接(connect())、数据传输(send()、recv()、sendto()、recvfrom())和关闭套...

    glibc-linuxthreads-2.3.3.tar.gz

    glibc的Linuxthreads是早期实现线程支持的重要组件,它的存在使得多线程编程在Linux上变得可能。本文将详细探讨glibc-linuxthreads-2.3.3这个特定版本,了解其特性、功能以及在Linux系统中的作用。 首先,glibc-...

    linux-api-2.6.22.rar_linux-api-2.6.22_linux-api-2.6.22.chm

    Linux API是一组预先定义好的函数,程序员可以使用这些函数来实现特定的操作,如文件操作、进程控制、网络通信等。API的稳定性和一致性对于开发跨平台的应用程序至关重要。Linux API 2.6.22是该系列的一个版本,包含...

    protoc-3.5.1-linux-x86_64.zip

    标题中的"protoc-3.5.1-linux-x86_64.zip"是指Google开源的Protocol Buffers(简称protobuf)编译器的3.5.1版本的Linux 64位二进制包。Protocol Buffers是一种序列化数据的框架,它允许开发者定义数据结构,然后生成...

    linux-c-api-ref.zip_linux api_linux-c-api-ref

    2. **文件I/O**:Linux中的文件操作是基于文件描述符的,`open()`函数用于打开文件并返回一个描述符,`read()`和`write()`则通过这个描述符读写数据。此外,还有`close()`用于关闭文件,`lseek()`改变文件读写位置,...

    glibc-2.28.tar.gz.7z

    4. 网络通信:`socket()`、`bind()`、`listen()`和`accept()`等函数构建网络服务。 5. 错误处理:`perror()`、`strerror()`等函数用于获取错误信息。 五、总结 glibc 2.28不仅是一个C库,它是Linux系统与应用程序...

    node-v0.8.9-linux-x86.tar.gz

    5. **文件系统操作**:Node.js 提供了丰富的 API 来操作文件系统,如读写文件、创建目录等,这在服务器端编程中非常实用。 6. **HTTP 服务器**:Node.js 内置了 HTTP 模块,可以轻松创建高性能的 Web 服务器,这也...

    Linux-C-function-user.rar_linux user

    9. **网络编程**:涉及socket编程,包括TCP/IP连接、套接字选项、服务器和客户端的实现等。 10. **并发和多线程**:介绍如何创建和管理线程,以及同步和互斥的概念,如mutex, semaphore, condition variable等。 ...

    diveintopythonzh-cn.tar.gz

    4. **函数式编程**:介绍函数式编程概念,如高阶函数、闭包、装饰器以及列表推导式。 5. **文件操作**:讲述如何读写文件,处理文本和二进制数据,以及文件对象的高级用法。 6. **正则表达式**:讲解如何使用...

    RXTX-2-2-20081207-Linux-x86_64.zip

    4. **跨平台兼容性**:虽然这里提供的版本是针对Linux 64位系统的,但RXTX库也支持Windows、Mac OS X和其他Unix变体,这使得开发跨平台的串行通信应用变得更加容易。 5. **动态加载**:RXTX使用JNI(Java Native ...

    linux-c-develop.rar

    9. **网络编程**:在Linux下,C程序员可以使用套接字API进行网络通信,包括`socket`创建套接字,`bind`绑定地址,`listen`监听连接,`accept`接受连接,`send`和`recv`发送接收数据等。 10. **动态库链接**:C程序...

    pthreads-w32-2-9-1-release.zip

    4. **线程安全函数**:在多线程环境下,不是所有C库函数都是线程安全的,需要使用线程安全的函数或自行处理同步问题。 5. **线程退出和资源释放**:使用`pthread_join()`等待线程结束,或者`pthread_detach()`让...

Global site tag (gtag.js) - Google Analytics