socket的创建和连接
socket编程
socket的概念
Socket(套接字)是计算机网络编程中的一个基本概念,它为应用程序提供了访问底层网络协议的接口,使得进程间能够通过网络进行通信。在更广泛的意义上,Socket 是操作系统提供的一个抽象层,用于简化网络编程并隐藏复杂的网络协议细节。
Socket 是两个进程间通信的端点,每个 Socket 都有唯一的地址,这个地址包括 IP 地址和端口号。IP 地址用于定位网络上的主机,而端口号则用于区分同一台主机上的不同服务。
socket的类型
socket 可以分为几种类型,主要依据它们支持的协议和通信模式:
- 流式 Socket (SOCK_STREAM): 基于 TCP 协议,提供面向连接的服务,保证数据的顺序传输,且不会丢失数据。
- 数据报 Socket (SOCK_DGRAM): 基于 UDP 协议,提供无连接服务,数据报文独立传输,不保证数据的顺序和完整性,但传输效率较高。
- 原始 Socket (SOCK_RAW): 直接访问 IP 层,允许应用程序直接处理 IP 数据包,常用于网络分析或特殊用途的软件。
socket提供的函数
- socket()创建一个新的确定类型的套接字,类型用一个整型数值标识,并为它分配系统资源。
- bind()一般用于服务器端,将一个套接字与一个套接字地址结构相关联,比如,一个指定的本地端口和IP地址。
- listen()用于服务器端,使一个绑定的TCP套接字进入监听状态。
- connect()用于客户端,为一个套接字分配一个自由的本地端口号。 如果是TCP套接字的话,它会试图获得一个新的TCP连接。
- accept()用于服务器端。 它接受一个从远端客户端发出的创建一个新的TCP连接的接入请求,创建一个新的套接字,与该连接相应的套接字地址相关联。
- send()和- recv(),或者- write()和- read(),或者- recvfrom()和- sendto(),用于往/从远程套接字发送和接受数据。
- close()用于系统释放分配给一个套接字的资源。 如果是TCP,连接会被中断。
- gethostbyname()和`gethostbyaddr()
- select()用于修整有如下情况的套接字列表: 准备读,准备写或者是有错误。
- poll()用于检查套接字的状态。 套接字可以被测试,看是否可以写入、读取或是有错误。
- getsockopt()用于查询指定的套接字一个特定的套接字选项的当前值。
- setsockopt()用于为指定的套接字设定一个特定的套接字选项。
1. socket()
- 作用:创建一个新的 Socket。
- 参数:- int domain:地址族,如- AF_INET(IPv4)或- AF_INET6(IPv6)。
- int type:Socket 类型,如- SOCK_STREAM(面向连接,流式)或- SOCK_DGRAM(无连接,数据报)。
- int protocol:协议,通常是- 0,表示使用与- type关联的默认协议。
 
2. bind()
- 作用:将 Socket 与本地地址(IP 地址和端口号)相关联。
- 参数:- int sockfd:Socket 文件描述符。
- const struct sockaddr *addr:指向包含地址信息的- sockaddr结构体的指针。
- socklen_t addrlen:- sockaddr结构体的长度。
 
3. listen()
- 作用:使 Socket 准备接收连接,通常用于服务器端。
- 参数:- int sockfd:Socket 文件描述符。
- int backlog:待处理连接请求的最大队列长度。
 
4. accept()
- 作用:接受传入的连接请求,并返回一个新的 Socket 文件描述符用于通信。
- 参数:- int sockfd:监听的 Socket 文件描述符。
- struct sockaddr *addr:可选参数,用于存储客户端的地址信息。
- socklen_t *addrlen:可选参数,用于存储地址信息的长度。
 
5. connect()
- 作用:初始化与远程主机的连接,通常用于客户端。
- 参数:- int sockfd:Socket 文件描述符。
- const struct sockaddr *addr:指向包含远程主机地址信息的- sockaddr结构体的指针。
- socklen_t addrlen:- sockaddr结构体的长度。
 
6. send()
- 作用:发送数据到已连接的 Socket。
- 参数:- int sockfd:Socket 文件描述符。
- const void *buf:指向要发送数据的缓冲区的指针。
- size_t len:要发送的数据长度。
- int flags:发送标志,如- MSG_DONTROUTE。
 
7. recv()
- 作用:从 Socket 接收数据。
- 参数:- int sockfd:Socket 文件描述符。
- void *buf:接收数据的缓冲区。
- size_t len:缓冲区的大小。
- int flags:接收标志,如- MSG_PEEK。
 
8. sendto()
- 作用:向特定地址发送数据,通常用于无连接的 Socket(如 UDP)。
- 参数:与 send()类似,额外包括目标地址和地址长度。
9. recvfrom()
- 作用:接收数据并返回源地址信息,通常用于无连接的 Socket(如 UDP)。
- 参数:与 recv()类似,额外包括源地址信息和地址长度。
10. close()
- 作用:关闭 Socket 文件描述符,释放资源。
- 参数:- int sockfd:要关闭的 Socket 文件描述符。
 
11. setsockopt()
- 作用:设置 Socket 的选项,如超时、重用地址等。
- 参数:- int sockfd:Socket 文件描述符。
- int level:设置选项的级别,如- SOL_SOCKET或- IPPROTO_TCP。
- int optname:选项名称。
- const void *optval:指向选项值的指针。
- socklen_t optlen:选项值的长度。
 
12. getsockopt()
- 作用:获取 Socket 的选项。
- 参数:与 setsockopt()类似。
13. shutdown()
- 作用:关闭 Socket 的读取或写入方向。
- 参数:- int sockfd:Socket 文件描述符。
- int how:关闭的方向,如- SHUT_RD(读取方向)或- SHUT_WR(写入方向)。
 
注意事项
- 使用 Socket 编程时,应确保正确处理错误情况,检查每个函数的返回值,并适当地处理任何错误代码。
- 对于某些函数,如 send()和recv(),如果在非阻塞模式下使用,可能需要处理 EAGAIN 或 EWOULDBLOCK 错误码,这表明操作无法立即完成。
- 在实际编程中,根据具体需求,可能还需要使用到其他函数,例如 select()或poll()用于多路复用,或者fork()和exec()用于创建子进程处理连接。
TCP socket通信流程

服务器端流程如下:
- 创建服务器的socket
- 初始化sever_addr(服务器地址)
- 将socket和server_addr绑定 bind
- 开始监听listen
- 开一个循环保证服务器不会结束,不断的accept接入的客户端请求,进行读写操作write和read(send()和recv()也行)
- 关闭socket
| 1 | 
 | 
客户端流程如下:
- 创建客户端socket
- 初始化server_addr
- 连接到服务器connect
- 利用write和read进行读写操作 (send()和recv()也行)
- 关闭socket
| 1 | 
 | 
