前言
SOCKET 是对TCP/IP的封装与应用。
在同一个互联网上,通过IP地址和端口号与协议,二台主机则可以互相锁定特定的进程。
SOCKET 是一种特殊的文件。使我们不必了解TCP/IP等协议即可完成对话。
对他的操作也和普通文件类似“open----write/read----close"。
1:创建一个SOCKET
#include <sys/types.h>
#include <sys/socket.h>
int socket(int domain, int type, int protocol);
socket函数相当于open或者是creat函数
domain为协议域 常用的协议域为AF_INET(IPV4)、AF_INET6(IPV6)
type为socket文件的类型 常用的文件类型为SOCK_STREAM: 提供面向连接的稳定数据传输,即TCP协议。
protocol为协议 通常填0,系统自动根据type来配对 。
他的返回值是SOCKET文件的描述字,用int型的变量来接取;
2:赋予SOCKET地址
在互联网中,而机交互可以看成二个SOCKET在对话。他们彼此之间靠IP+协议+端口来确认彼此。
我把IP+协议+端口可以看作SOCKET的地址
#include <sys/types.h>
#include <sys/socket.h>
int bind(int sockfd, const struct sockaddr *my_addr, socklen_taddrlen);
bind用来给SOCKET绑定地址
sockfd为SOCKET的描述字;
struct sockaddr *my_addr为一类结构体,里面存放着SOCKET的地址,根据SOCKET协议域不同而选择不同地址结构体
socklen_taddren为结构体地址的大小sizeof(my_addr)
IPV4的地址结构体
struct sockaddr_in {
sa_family_t sin_family; //协议域,如AF_INET
in_port_t sin_port; //端口号,如htons(8000)
struct in_addr sin_addr; //ip号结构体
};
struct in_addr {
uint32_t s_addr; //ip号,如果是服务器可以用htonl(INADDR_ANY);系统自动选择本机IP;客户端则须指定IP
}
IPV6的结构体
struct sockaddr_in6 {
sa_family_t sin6_family; /* AF_INET6 */
in_port_t sin6_port; /* port number */
uint32_t sin6_flowinfo; /* IPv6 flow information */
struct in6_addr sin6_addr; /* IPv6 address */
uint32_t sin6_scope_id; /* Scope ID (new in 2.4) */
};
struct in6_addr {
unsigned char s6_addr[16]; /* IPv6 address */
};
当我们创建了一个SOCKET并给他绑定地址后,便需要实时来监听是否有其他SOCKET想与其通话
#include <sys/socket.h>
int listen(int sockfd, int backlog);
sockfd为需要监听SOCKET的描述字
backlog是允许排队的数量
4:向其他SOCKET发起链接
当本机SOCKET想与其他SOCKET进行通话,便需要发送请求
#include <sys/types.h>
#include <sys/socket.h>
int connect(int sockfd, const struct sockaddr *serv_addr, socklen_t addrlen);
sockfd为本机SOCKET的描述字
struct sockaddr *sery_addr为目标SOCKET的地址
addrlen为目标SOCKET地址的长度
connect为给sockfd分配一个IP和端口;
5:接受其他SOCKET发起的链接
当其他SOCKET向本机SOCKET发送请求时,我们接受后便可以通话
#include <sys/types.h>
#include <sys/socket.h>
int accept(int sockfd, struct sockaddr *addr, socklen_t *addrlen);
sockfd为本机socket的描述字
sockaddr *addr为接受其他SOCKET的地址,如果是接受任意一个可以设为NULL
addrlen为addr大小,任意可以设为NULL
他的返回值是请求通话的SOCKET描述字.
6:接受其他SOCKET发来的数据
当二个SOCKET建立起通话时,二者之间可以进行数据交换,可以利用read、recv等函数读取另一端发来的数据
#include <sys/types.h>
#include <sys/socket.h>
ssize_t recv(int s, void *buf, size_t len, int flags);
s为accept接受的SOCKET的返回值
buf为指定的一块空间存放发来的信息
len为指明该空间的大小
flag一般为0;有兴趣用man自己查看
返回值为接受到的数据
7:向其他SOCKET发送数据
当二个SOCKET建立起通话,二者之间可以进行数据交换,可以利用write、send等函数向另一端发送数据
#include <sys/types.h>
#include <sys/socket.h>
ssize_t send(int s, const void *buf, size_t len, int flags);
s为发送端的SOCKET描述字
bud为发送数据存放的空间
flags为发送数据的大小
8:关闭通话
当我们发送或接受完指定的数据后,便可以进行关闭通话
#include <unistd.h>
int close(int fd);
fd为SOCKET描述字