Linux SOCKET介绍

栏目: 服务器 · 发布时间: 6年前

内容简介:socket 是一种IPC方法,它允许位于同一主机(计算机)或使用网络连接起来的不同主机上的应用程序之间交换数据。socket主要有两种类型:流(SOCK_STREAM)和数据报(SOCK_DGRAM)。这两种socket类型在UNIX和Internet domain中都得到了支持。流(SOCK_STREAM)是一个双向字节流通信信道

socket 是一种IPC方法,它允许位于同一主机(计算机)或使用网络连接起来的不同主机上的应用程序之间交换数据。

2.创建一个socket

#include<sys/socket.h>
int socket(int domain,int type,int protocol);
//return file descriptor on success or -1 on error
复制代码

2.1 通信domain

  • 识别出一个socket的方法(即socket“地址”的格式);
  • 通信范围(即是在位于同一主机上的应用程序之间还是位于使用一个网络连接起来的不同主机上的应用程序之间)。
Linux SOCKET介绍

2.2 socket 类型

socket主要有两种类型:流(SOCK_STREAM)和数据报(SOCK_DGRAM)。这两种socket类型在UNIX和Internet domain中都得到了支持。

Linux SOCKET介绍
Linux SOCKET介绍

流(SOCK_STREAM)是一个双向字节流通信信道

数据报(SOCK_DGRAM)允许数据以被称为数据报的消息的形式进行交换。

2.3 protocol

protocol参数应设某个协议类型常值,或者设为0,以选择给定family和type组合的系统默认值。

3.将socket绑定到地址: bind()

#include<sys/socket.h>
int bind(int sockfd,const struct sockaddr *addr,socklen_t addrlen)
复制代码
  • sockfd 参数是在上一个socket()调用中获得的文件描述符。
  • addr参数是一个指针,它指向了一个指定该socket绑定到的地址的结构。传入这个参数的结构的类型取决于socket domain。
  • addrlen参数指定了地址结构的大小。

一般来讲,会将一个服务器的socket绑定到一个众所周知的地址——即一个固定的与服务器进行通信的客户端应用程序提前就知道的地址。

3.1 通用socket地址结构:struct sockaddr

这个类型的唯一用途是将各种domain特定的地址结构转换成单个类型以供socket系统调用中的各个参数使用。

/* Structure describing a generic socket address.  */
struct sockaddr
  {
    __SOCKADDR_COMMON (sa_);	/* Common data: address family and length.  */
    char sa_data[14];		/* Address data.  */
  };


/* Structure describing an Internet socket address.  */
struct sockaddr_in
  {
    __SOCKADDR_COMMON (sin_);
    in_port_t sin_port;			/* Port number.  */
    struct in_addr sin_addr;		/* Internet address.  */

    /* Pad to size of `struct sockaddr`.  */
    unsigned char sin_zero[sizeof (struct sockaddr) -
			   __SOCKADDR_COMMON_SIZE -
			   sizeof (in_port_t) -
			   sizeof (struct in_addr)];
  };

/* Structure describing the address of an AF_LOCAL (aka AF_UNIX) socket.  */
struct sockaddr_un
  {
    __SOCKADDR_COMMON (sun_);
    char sun_path[108];		/* Path name.  */
  };


复制代码

4.流socket

Linux SOCKET介绍

4.1 监听接入连接:listen()

#include<sys/socket.h>
int listen(int sockfd,int backlog);
//return 0 on success,or -1 on error
复制代码

listen()系统调用将文件描述符sockfd引用的流socket标记为被动。这个socket后面会被用来接受来自其他(主动的)socket连接。

无法在一个已连接的socket(即已经成功执行connect()的socket或由accept()调用返回的socket)上执行listen().

Linux SOCKET介绍
  • backlog:允许限制未决连接的数量。在这个限制之内的连接请求会立即成功。(TCP socket会有点复杂)而在之外的连接请求就会阻塞直到一个未决的连接被接受(通过accept()),并从未决连接队列删除为止。

4.2接受连接:accept()

#include<sys/socket.h>
int accept(int sockfd,struct sockaddr *addr,socklen_t *addrlen);
//return file descriptor on success, or -1 on error
复制代码

acceot()系统调用在文件描述符sockfd引用的监听流socket上接受一个接入连接。如果在调用accept()时不存在未决的连接,那么调用就会阻塞直到有连接请求到达为止。

accept() 调用返回的函数结果是已连接的socket的文件描述符。监听socket(sockfd)会保持打开状态,并且可以被用来接受后续的连接。

  • addr: 传入accept()的剩余参数会返回对端socket的地址。addr参数指向了一个用来返回socket地址的结构。这个参数的类型取决与socket domain(与bind()一样)。
  • addrlen: 它指向一个整数,在调用执行之前必须要将这个整数初始化为addr指向的缓冲区的大小,这样内核就知道有多少空间可用于返回socket地址了。

如果不关心对等socket的地址,那么可以将addr和addrlen分别指定为NULL和0。(也可以在后面某个时刻使用getpeername()系统调用来获取对端的地址。)

4.3连接到对等socket:connect()

#include<sys/socket.h>
int connect(int sockfd,const struct sockaddr *addr,socketlen_t addrlen);
//return 0 on success,or -1 on error
复制代码

connect() 系统调用将文件描述符sockfd引用的主动socket连接到地址通过addr和addrlen指定的监听socket上。

addr和addrlen参数的指定方式与bind()调用中对应参数的指定方式相同。

4.4 流socket I/O

Linux SOCKET介绍
  • 要执行I/O需要使用read()和write()系统调用。由于socket是双向的,因此在连接的两端都可以使用这两个调用。
  • 一个socket可以使用close()系统调用来关闭或在应用程序终止之后关闭。之后当对等应用程序试图从连接的另一端读取数据时将会收到文件结束(当所有缓冲数据都被读取之后)。如果对等应用程序试图向其socket写如数据,那么它就会收到一个SIGPIPE信号,并且系统调用会返回EPIPE错误。

4.5 连接终止:close()

终止一个流socket连接的常见方式是调用close()。如果多个文件描述符引用了同一个socket,那么当所有描述符被关闭之后连接就会终止。 假设在关闭一个连接之后,对等应用程序崩溃或没有读取或错误处理了之前发生给它的数据。在这种情况下就无法知道已经发生了一个错误。如果需要确保数据被成功地读取和处理,那么就必须要在应用程序中构建某种确认协议。这通常由一个从对等应用程序传过来的显式的确认消息构成。

5.数据报 socket

Linux SOCKET介绍

5.1 交换数据报:recvfrom() 和 sendto()

#include<sys/socket.h>
ssize_t recvfrom(int sockfd,void* buffer,size_t length,int flags,struct sockaddr *src_addr,sockeln_t *addrlen);
ssize_t sendto(int sockfd,const void* buffer,size_t length,int flags,const struct sockaddr *dest_addr,socklen_t addrlen);
复制代码

这两个系统调用的返回值和前三个参数与read()和write()中的返回值和相应参数是一样的。

sockaddr和socklen_t参数被用来获取或指定与之通信的对等的地址。

对于recvfrom(),src_addr和addrlen参数会返回用来发送数据报的远程socket的地址。

对于sendto(),dest_addr和addrlen参数指定了数据报发送到的socket。


以上所述就是小编给大家介绍的《Linux SOCKET介绍》,希望对大家有所帮助,如果大家有任何疑问请给我留言,小编会及时回复大家的。在此也非常感谢大家对 码农网 的支持!

查看所有标签

猜你喜欢:

本站部分资源来源于网络,本站转载出于传递更多信息之目的,版权归原作者或者来源机构所有,如转载稿涉及版权问题,请联系我们

BLOG启示录

BLOG启示录

胡嘉玺 / 清华大学出版社 / 2010-7 / 48.00元

《BLOG启示录:WordPress博客建设与经营》分三大部分,共17章。第一部分(1~5章)主要是介绍Web 2.0、博客,以及LAMP的安装和架设,更有完整的主机、域名、DNS、WordPress安装、申请、交费等步骤,读者即使对计算机、主机、网络、域名等知识完全不懂,也可以依照《BLOG启示录:WordPress博客建设与经营》的步骤来落实整个WordPress基础建设的架构及安装。 ......一起来看看 《BLOG启示录》 这本书的介绍吧!

MD5 加密
MD5 加密

MD5 加密工具

UNIX 时间戳转换
UNIX 时间戳转换

UNIX 时间戳转换

正则表达式在线测试
正则表达式在线测试

正则表达式在线测试