`
bnot71bnot
  • 浏览: 13823 次
最近访客 更多访客>>
社区版块
存档分类
最新评论

Linux 网络编程基础(一) ---------------客户端/服务器的简单实现

 
阅读更多

Linux 网络编程基础(一) ---------------客户端/服务器的简单实现
2011年06月15日
  在80年代早期,加利福尼亚大学伯克利分校的一个研究组,将TCP/IP软件一直到UNIX操作系统上。作为实现该项目的一部分,他们设计了一种接口,应用程序可以通过这个接口方便的进行通信。这样做的结果是出现了插件接口(Barkeley Socket)。 
  
  图1. Socket层次 
  Socket实质上提供了进程通信的端点,进程通信之前,双方必须首先各自创建一个端点,否则是没有办法建立联系并相互通信的。 
  每一个Socket都一个半相关描述: 
  {协议, 本地地址, 本地端口} 
  完整的Socket的描述: 
  {协议, 本地地址, 本地端口, 远程地址, 远程端口}  首先,服务器应用程序用系统调用socket()来创建一个socket,它是系统分配给该服务器进程的类似文件描述符的资源,不能与其他进程共享。 
  接下来,需要给socket绑定,本地socket绑定的是Linux文件系统中的文件名,一般放在/tmp或者/usr/tmp目录中。对于网络socket,要和客户连接的特定网络相关的服务标示符(端口号或者访问点)。可以使用系统调用bind()来绑定socket,然后服务器进程就用listen()创建一个队列将客户的连接存入队列,再使用accept()接收客户的连接。 
  服务器调用accept()时会创建一个和原有的socket不同的新socket。这个新socket只用于与这个特定的客户进行通信,而原socket保留下来继续处理来自其他客户的连接。  客户端是首先调用socket()创建一个未绑定的socket,然后将服务器的socket作为一个地址调用connect()与服务器建立连接。 
  
  图2 面向连接(TCP)的Socket工作流程 
  
  图3 UDP的socket工作流程  套接字有三种类型:流式套接字(SOCK_STREAM),数据报套接字(SOCK_DGRAM)及原始套接字。  流式的套接字可以提供可靠的、面向连接的通讯流。如果你通过流式套接字发送顺序的数据:"1"、"2",那么数据到达的顺序也是"1"、"2"。流式套接字在AF_INET域中使用TCP协议来保证数据传输的正确性及顺序性。TCP是TCP/IP协议的前半部分,IP只处理网络路由。  数据报协议定义了一种无连接的服务,数据通过相互独立的报文进行传输,是无序的,并且不保证可靠,无差错。它使用UDP/IP协议。UDP将数据打包,贴上IP地址,然后发送。这个过程不需要建立连接。  原始套接字主要用于一些协议的开发,可以进行比较底层的操作。它功能强大,但是没有流式套接字和数据报套接字使用方便,一般的程序也不涉及到原始套接字。  AF_INET与AF_UNIX域的套接字地址结构不相同,分别为struct sockaddr_in, struct sockaddr_un。  IP地址结构in_add定义为: 在当前的Linux系统中,由X/Open规范定义的类型sa_family_t在头文件sys/un.h中声明,它是短整数类型。另外sun_path指定的路径名长度也是有限制的(Linux规定的是108个字符)。  因为每一个机器内部对变量的字节存储顺序不同(有的系统是高位在前,低位在后,有的系统是的低位在前,高位在后),而网络传输的字节序需要统一。所以,对于主机字节序和网络字节序不同的机器,就一定要对数据进行转换(例如IP地址的表示和端口号的表示)。如果主机字节序和网络字节序相同,也要调用转换函数,真正转换 还是不转换由系统函数自己决定。 
  转换函数: 这些函数将16位和32位整数在主机字节序和标准的网络字节序之间进行转换。"h"代表主机"host","n"代表网络"network","l"代表"long","s"代表"short"。  socket()系统调用创建一个套接字并返回一个描述符,该描述符可以用来访问该套接字。 创建的套接字是一条通信线路的一个端点,domain参数指定协议族,type参数指定这个套接字的通信类型,protocol参数指定使用的协议。 
  最常用的套接字域是AF_UNIX和AF_INET,前者用于通过UNIX和Linux文件系统实现的本地套接字,后者用于UNIX网络套接字。AF_INET套接字可以用于通过包括互联网在内的TCP/IP网络进行通信的程序。 
  参数type指定这个socket的通信类型,protocol参数指定使用的协议。通信所需的协议一般是由socket类型来决定,通常不需要进行选择。只有当需要选择的时候,才会用到protocol参数。将protocol参数设置为0表示使用默认协议。 
  socket返回一个描述符,类似于文件描述符。这个描述符可以用于read(),write()等系统调用来连接另一个socket。 
  实例:创建socket,AF_INET,SOCK_STREAM。 在调用socket()获得描述符之后,需要对该套接字进行绑定。AF_UNIX套接字会关联到一个文件系统的路径名,而AF_INET套接字会关联到一个IP端口号。 bind将参数address中的地址分配给与文件描述符socket关联的未命名套接字。address_len传递地址结构体的长度。 地址的长度取决于地址的类型。bind系统调用需要将struct sockaddr_in或struct sockaddr_un指针转换成struct sockaddr *类型。 
  bind在调用成功时返回0, 失败是返回-1并设置errno。  EBADF 文件描述符无效 ENOTSOCK 文件描述符对应的不是一个socket EINVAL 文件描述符对应的是一个已经绑定的socket EADDRNOTAVAIL 地址不可用 EADDRINUSE 地址已经绑定了一个socket 表2 errno值  AF_UNIX还有一些错误代码  表3 AF_UNIX部分errno值 
  实例: 为了能够在套接字上接受进入的链接,服务器要建立一个队列来保存未处理的请求。 参数backlog设置队列中可以容纳的未处理连接的最大个数。超过这个数字后,剩下的连接会被拒绝。backlog常用值为5…… 
  listen函数会在成功时返回0,失败时返回-1,错误代码包括EBADF,EINVAL和ENOTSOCK。 
  实例: 一旦服务器程序创建并绑定了socket之后,他就可以通过用accept()来等待客户建立对该socket的连接。 accept只有当有客户程序尝试连接到由socket参数指定的socket上时才返回。accept将创建一个新socket来与该客户进行通信,将该socket描述符作为返回值。之后的读写动作都关联到该socket描述符上。 
  参数socket所关联的套接字必须首先已经被bind绑定,而且有listen为其分配连接队列。参数address表示客户的地址,如果不关心客户的地址值可设为空指针。 
  如果socket没有未处理的连接accept将阻塞直到队列中有未处理的连接。可以通过设置O_NONBLOCK来改变。实例: 发生错误时,accept会返回-1。  客户程序通过与服务器监听套接字之间绑定的方法连接到服务器。 参数socket指定的套接字将连接到参数address指定的服务器的socket上。 
  成功时,connect返回0,失败返回-1。 
  如果连接不能立刻建立,connect将阻塞到超时时间,超过超时时间连接将被放弃,连接失败。  可以通过close()来终止服务器与客户端的socket连接。 send()同样可以发送数据,与write()不同的是,send()只能用于socket数据的发送。 参数中,buff指向要发送的数据,len为要发送数据的长度, flags一般为0。 
  成功时send返回发送的字节数,失败返回-1。  与send()相同,recv()也只能用于socket的数据发送。 buf指向存放接收数据的缓冲区,len为数据长度,flags一般为0。 
  成功时recv()返回接收的字节数,失败时返回-1。  sendto需要带上发送目的地的地址信息,可以用于UDP通讯的实现,TCP中也可以使用sendto()。 buff指向要发送的数据,len为要发送的数据的长度,flags一般为0,addr_to携带发送目的IP的信息,addr_len是地址信息的长度。 
  成功时,sendto返回发送的字节数,失败返回-1。  recvfrom()与sendto配套使用,实现数据的收发。 buff指向接收数据的缓冲区,len为数据长度,flags一般为0, addr_from存放数据来源的IP地址,addr_len为地址信息的长度。 
  recvfrom成功时返回接收的字节数,失败返回-1。  connect(),recv()都是阻塞性函数,当需求的资源没有准备好的时候,调用函数的进程将进入休眠状态,这样就无法处理I/O多路复用的情况了。 
  解决这个问题的方法与普通的文件操作相同:使用fcntl()或者select()函数。相比较fcntl(),select()函数还可以设置等待时间,功能更为强大。 
  --------
分享到:
评论

相关推荐

    黑马_Linux网络编程-网络基础-socket编程-高并发服务器

    ### 黑马_Linux网络编程-网络基础-socket编程-高并发服务器 #### 知识点概述 本篇文章旨在深入解读“黑马_Linux网络编程-网络基础-socket编程-高并发服务器”相关的核心概念和技术要点,包括网络基础知识、常用...

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

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

    Linux网络编程-基础

    Linux 网络编程是一种在 Linux 操作系统下进行网络通信的编程方式,通过使用套接字(socket)和各种网络函数来实现网络通信。在 Linux 系统中,网络编程可以分为客户端和服务器端两个部分,客户端程序主动与外部程序...

    linux网络编程详解.pdf

    - **客户/服务器模型**:讲解客户端和服务端的概念,以及这种模型在实际网络应用中的实现方式和应用场景。 #### 二、操作系统背景 - **UNIX的历史**: - **Unix诞生前的故事**:回顾Unix出现之前的计算机操作系统...

    linux网络基础和网络编程

    本文将深入探讨这个主题,从Linux网络的基础知识开始,逐步讲解到Socket编程以及如何实现高并发服务器。 1. Linux网络基础: - 网络模型:Linux遵循OSI七层网络模型(物理层、数据链路层、网络层、传输层、会话层...

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

    网络基础协议的概念: 在计算机网络中,协议是一系列规则和约定的集合,用于控制网络中不同设备间的通信方式。...通过深入理解这些知识点,可以更好地掌握Linux网络编程,以及如何构建高并发服务器。

    Linux网络编程-文字版.pdf

    Linux网络编程是计算机网络领域的一项基础而核心的技术。它涉及到操作系统内核级别的通信机制,尤其是在Linux这样的类Unix系统上,网络编程的基本单元是套接字(Socket)。下面将从几个方面详细解析Linux网络编程的...

    Linux网络编程-简单的客户端和服务器通讯程序开发入门.pdf

    【Linux网络编程基础】 在Linux环境下进行网络编程,首要任务是理解客户端和服务器端的概念。一个网络程序通常由这两部分组成:客户端发起连接请求,而服务器端则在特定的端口上监听,等待客户端的连接。客户端和...

    网络编程---ftp客户端程序实验报告

    2. **套接字编程**:套接字是网络通信的基础,实验要求设计程序流程,利用套接字API实现客户端与服务器之间的通信。这包括创建套接字、绑定、监听、连接和数据交换等步骤。 3. **操作系统网络API**:在Windows/...

    Linux/UNIX网络编程》-甘刚-电子教案

    1. **套接字接口**:这是Linux和UNIX系统中进行网络编程的基础,包括socket()函数创建套接字,bind()将套接字与本地地址关联,listen()设置服务器监听模式,accept()接收连接请求,connect()客户端连接服务器,以及...

    linux服务器客户端1对1聊天

    总的来说,实现Linux服务器客户端1对1聊天程序涉及了网络编程的基础知识,包括Socket的创建、连接、数据交换以及错误处理等。通过阅读和理解`server1.c`和`client1.c`的源代码,我们可以深入学习这些概念,并且可以...

    linux网络编程和TCP-IP详解

    在IT领域,Linux网络编程和TCP/IP协议是网络开发的核心部分。这些概念和技术构成了互联网通信的基础,对于系统管理员、软件开发者以及任何与网络打交道的人来说都至关重要。以下是对这些主题的详细解析: 首先,...

    linux 编程教程 -- linux下编程入门

    - 客户端/服务器模型:理解并实现基本的客户端-服务器应用程序。 - 多路复用:利用select、poll和epoll进行I/O多路复用。 7. **系统调用与API** - 系统调用:了解常见的系统调用,如fork、exec、wait、exit等。 ...

    实例101 Linux下编程实现服务器与客户端的连接.rar_linux 编程_linux 服务器_linux下编程_服务器

    本实例"实例101 Linux下编程实现服务器与客户端的连接"主要涵盖了网络编程的基础知识,以及如何在Linux系统中应用这些知识来创建服务端和客户端程序。下面我们将深入探讨相关知识点。 首先,我们要了解的是TCP/IP...

    01_Linux网络编程-网络基础-socket编程-高并发服务器1

    【网络编程基础与Socket编程】 网络编程是计算机通信的核心,涉及多层协议栈,以便不同设备间能够有效地交换数据。本文将重点介绍网络基础、协议概念以及常见的协议,并探讨网络应用程序设计模式,如C/S模式和B/S...

    Linux网络编程 Linux网络编程.TXT

    #### 六、网络编程基础 - **套接字(Socket)**:网络编程的核心,提供了一种在不同主机间通信的机制。 - **Socket编程模型**:包括创建套接字、绑定地址、监听连接、接受连接、数据发送与接收、关闭套接字等步骤。...

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

    Linux网络编程涉及网络基础知识,尤其是Socket编程和高并发服务器的实现。网络协议是通信的规则,比如文件传输协议FTP,它的基本流程包括三次数据传输:文件名、文件大小和文件内容。随着协议的发展和标准化,形成了...

    Linux下的服务器与客户端通信

    在Linux操作系统中,服务器与客户端之间的通信是网络编程的基础,主要依赖于TCP/IP协议栈。本文将详细解析基于Linux的服务器与客户端通信实现过程,包括关键概念、原理以及代码实现。 首先,我们要理解服务器...

Global site tag (gtag.js) - Google Analytics