Linux SOCKET介绍

Linux SOCKET介绍1.概述socket是一种IPC方法,它允许位于同一主机(计算机)或使用网络连接起来的不同主机上的应用程序之间交换数据。2.创建一个socket#include<sys/socket.h>intsocket(intdomain,inttype,intprotocol);//returnfiledescriptoronsuccessor-1onerror复制代码2.1通信domain识别出一个socket的方法(即socket“地址”的格式)

1.概述

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。

作者:Wu_XMing
链接:https://juejin.cn/post/6844903699551092750
来源:掘金
著作权归作者所有。商业转载请联系作者获得授权,非商业转载请注明出处。

今天的文章Linux SOCKET介绍分享到此就结束了,感谢您的阅读。

版权声明:本文内容由互联网用户自发贡献,该文观点仅代表作者本人。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如发现本站有涉嫌侵权/违法违规的内容, 请发送邮件至 举报,一经查实,本站将立刻删除。
如需转载请保留出处:https://bianchenghao.cn/24219.html

(0)
编程小号编程小号

相关推荐

发表回复

您的电子邮箱地址不会被公开。 必填项已用*标注