socket编程(中)
![在这里插入图片描述](https://i-blog.csdnimg.cn/blog_migrate/820c3c548118e43c707d154b26382cc9.jpeg#pic_center)
1.网络访问的是公网ip还是私网ip
- 客户端与服务器在同一台机器时,访问公网ip或私网ip都可以
- 客户端和服务器需要跨网络(不在同一台机器时),访问服务器公网ip
2.tcp的编程流程
- 服务端:创建套接字,绑定地址信息,监听,获取新连接,收发数据,关闭连接
- 客户端:创建套接字,不绑定地址信息(可以绑定),发起连接,收发数据,关闭连接
- 监听含义:监听tcp客户端新的链接,同客户端建立新的连接(注意:此时tcp连接的建立就在内核中完成了)
- 获取新连接的含义:获取新连接的套接字描述符,每一个tcp连接会产生一个套接字描述符
- 发起连接的含义:向服务端发起txp连接
3.相关函数
监听:
int listen(int sockfd,int backlog);
- sockfd:套接字描述符
- backlog:tcp并发连接数(已完成连接的大小)
- 未完成连接队列:还处于连接建立的连接被放在这个队列当中(可以理解为正在进行三次握手的连接在该队列)
- 已完成连接队列的大小:连接已经建立,可以正常通信的连接放在这个队列(可以理解为三次握手完毕的连接在该队列)
- 可以通过修改:/proc/sys/net/ipv4/tcp_max_syn_backlog当中的值,修改未完成连接队列的大小
- 返回值:成功为0,失败为-1
阻塞调用:
int accept(int sockfd,struct sockaddr *addr,socklen_t *addrlen);
- sockfd:套接字描述符
- addr:地址信息结构体,描述客户端地址信息的结构体(ip、端口)
- addrlen:地址信息的长度
- 返回值:成功返回新连接的套接字,失败返回-1
- 注意:如果已完成队列当中没有已经建立连接的连接,则阻塞;如果有获取新连接之后,就返回
- 返回的套接字:返回的新连接的套接字是为了和客户端进行通信的,并没有进行监听功能,同时含有客户端的地址信息
- 总结:服务端用socket创建出来的套接字描述符,是用来侦听套接字,侦听是否有新连接到来
服务端用accept创建出来的新连接套接字,就是同客户端通信的
连接:
int connect(int sockfd,const struct sockaddr *addr,socklen_t addrlen);
- sockfd:套接字描述符
- addr:地址信息结构,描述服务端地址信息(ip、端口)
- addrlen:地址信息长度
- 返回值:0为成功,-1则失败
- 注意:该函数不仅可以完成连接功能,如果客户端没有绑定,同时可以进行绑定客户端的地址信息
发送数据:
ssize_t send(int sockfd,const void *buf,size_t len,int flags);
- sockfd:套接字描述符(accept接收回来的,并非监听套接字)
- buf:发送buf指向空间的形容
- len:数据长度
- flags:0(阻塞发送)
- 返回值:成功返回发送字节的数量,失败返回-1
接收数据:
ssize_t resv(int sockfd,void *buf,size_t len,int flags);
- sockfd:套接字描述符
- buf:将接收到的数据存放在buf指定的空间,空间需要程序员提前开辟好
- len:期望接受的字节个数
- flags:0(阻塞接收)
- 返回值:成功,接收到的字节数量,0,对端关闭连接,-1,接收错误