socket网络通信
socket
能够解决的问题是客户端和服务器端进行交流的问题
服务器server
-
socket()
的作用是创建一个端点,然后返回一个fd
指向这个端点。包括分配fd
和分配tcb
进程控制块两。接受三个参数需要指定通信域domain(AF_INET, AF_INET6)
、指定通信语义type(SOCK_STREA,SOCK_DGRAM)
、指定通信协议protocol
(0代表为通信语义进行默认的协议配置),返回一个fd
,fd
是以bitmap
实现的。int fd = socket(AF_INET, SOCK_STREAM, 0);
-
bind()
的作用是将地址绑定到对应fd
的tcb
控制块上,这是因为socket
分配之后,会存在一个命令空间(地址族),接受三个参数fd
,地址,地址长度。struct sockaddr_in server; // 声明一个IPV4地址类型 socklen_t len = sizeof(server); memset(&server, 0 , sizeof(server)); server.sin_family = AF_INET; server.sin_port = htons(port); server.sin_addr.s_addr = inet_addr(IP); bind(fd, (struct sockaddr*)&server, &len);
-
``listen()
的作用是使
socket监听连接,接受两个参数
fd和
backlog,
backlog`指针最多挂起几个tcp连接。listen(fd, 10);
-
accept( )
的作用使接受完成的tcp
连接,接受三个参数,服务端fd
和客户端地址和客户长度,返回客户fd
。struct sockaddr_in server; // 声明一个IPV4地址类型 socklen_t len = sizeof(server); memset(&server, 0 , sizeof(server)); int clientfd = accept(fd, (struct sockaddr*)&client, &c_len);
客户端client
-
socket()
int fd = socket(AF_INET, SOCK_STREAM, 0);
-
bind()
,客户端可以进行bind,也可以不进行bind,不bind的话会默认分配地址和端口。struct sockaddr_in client; // 声明一个IPV4地址类型 socklen_t len = sizeof(client); memset(&server, 0 , sizeof(client)); server.sin_family = AF_INET; server.sin_port = htons(port); server.sin_addr.s_addr = inet_addr(IP); bind(fd, (struct sockaddr*)&client, &len);
-
connect()
的作用是将sockfd与对应地址fd进行连接,接受三个参数fd,地址,地址长度,返回0表示连接成功。struct sockaddr_in server; // 声明一个IPV4地址类型 socklen_t len = sizeof(server); memset(&server, 0 , sizeof(server)); server.sin_family = AF_INET; server.sin_port = htons(port); server.sin_addr.s_addr = inet_addr(IP); connect(fd, (struct sockaddr*)&server, &len)
注意
-
端口一旦被绑定,无法再次绑定
-
执行
listen
,可以通过netstat
查看状态 -
进入
listen
,并且会产生新连接状态 -
io
与tcp
连接状态 -
一个
fd
对应一个tcp
连接,唯一标识了一个客户 -
int clientfd = accept(sockfd, (struct sockaddr*) &client, (socklen_t*)sizeof(client));
这里对右值进行强转指针,那么右值会释放掉,那么指针就是未定义,所以要前面就开始定义。 -
sudo fuser -k 2000/tcp
杀死所有2000端口的tcp连接 -
没有
accept
就需要将fd IO
和tcp
连接分开讲,有accept
之后fd IO
和tcp
连接就相同声明周期,已建立TCP连接但是阻塞在accept()
-
IO
就是一个fd
,如果一个线程一个fd那么会产生很大的问题 -
stdin
,stdout
,stderror
分别是0,1,2fd,其它新建的连接会从3开始递增