写在前面
由于最近业务需要,代码里很多网络相关的网络相关的知识点都是自己不会的。于是狠狠的有针对性的恶补了一波。本文的话,按照顺序阅读的话就很好理解了。
大致分为:
【网络基础】初识Socket
【网络基础】三次握手和四次挥手
【网络基础】Socket 在握手和挥手调用了什么函数?
参考
1.为啥需要socket,socket是啥?
话不多说,先来一张基础知识的大图(网上找的,来源可见图上的水印)。socket来源 就是因为这个图里的表示层和会话层在实际的使用中不方便,且不用的应用层应用的使用方式不一样,为了方便使用就有了socket。说白了就是,把你的代码功能封装下,让别人用的时候不用管里面的实现,只需要查看接口就好。
TCP-IP.gif
这个图主要看4-7层就好,有个大体概念,暂时不用深究。
Socket是什么呢?
Socket是应用层与TCP/IP协议族通信的中间软件抽象层,它是一组接口。在设计模式中,Socket其实就是一个门面模式,它把复杂的TCP/IP协议族隐藏在Socket接口后面,对用户来说,一组简单的接口就是全部,让Socket去组织数据,以符合指定的协议。
2.socket 的地位是什么
首先看下socket的位置
socket的位置.png
到这里就应该明白了socket是个啥,在哪里了!
socket 的具体实现(就是内部的函数什么的)
我就直接拿OC里的代码吧
<socket.h>.png
__BEGIN_DECLS
int accept(int, struct sockaddr * __restrict, socklen_t * __restrict)
__DARWIN_ALIAS_C(accept);
int bind(int, const struct sockaddr *, socklen_t) __DARWIN_ALIAS(bind);
int connect(int, const struct sockaddr *, socklen_t) __DARWIN_ALIAS_C(connect);
int getpeername(int, struct sockaddr * __restrict, socklen_t * __restrict)
__DARWIN_ALIAS(getpeername);
int getsockname(int, struct sockaddr * __restrict, socklen_t * __restrict)
__DARWIN_ALIAS(getsockname);
int getsockopt(int, int, int, void * __restrict, socklen_t * __restrict);
int listen(int, int) __DARWIN_ALIAS(listen);
ssize_t recv(int, void *, size_t, int) __DARWIN_ALIAS_C(recv);
ssize_t recvfrom(int, void *, size_t, int, struct sockaddr * __restrict,
socklen_t * __restrict) __DARWIN_ALIAS_C(recvfrom);
ssize_t recvmsg(int, struct msghdr *, int) __DARWIN_ALIAS_C(recvmsg);
ssize_t send(int, const void *, size_t, int) __DARWIN_ALIAS_C(send);
ssize_t sendmsg(int, const struct msghdr *, int) __DARWIN_ALIAS_C(sendmsg);
ssize_t sendto(int, const void *, size_t,
int, const struct sockaddr *, socklen_t) __DARWIN_ALIAS_C(sendto);
int setsockopt(int, int, int, const void *, socklen_t);
int shutdown(int, int);
int sockatmark(int) __OSX_AVAILABLE_STARTING(__MAC_10_5, __IPHONE_2_0);
int socket(int, int, int);
int socketpair(int, int, int, int *) __DARWIN_ALIAS(socketpair);
#if !defined(_POSIX_C_SOURCE)
int sendfile(int, int, off_t, off_t *, struct sf_hdtr *, int);
#endif /* !_POSIX_C_SOURCE */
#if !defined(_POSIX_C_SOURCE) || defined(_DARWIN_C_SOURCE)
void pfctlinput(int, struct sockaddr *);
__API_AVAILABLE(macosx(10.11), ios(9.0), tvos(9.0), watchos(2.0))
int connectx(int, const sa_endpoints_t *, sae_associd_t, unsigned int,
const struct iovec *, unsigned int, size_t *, sae_connid_t *);
__API_AVAILABLE(macosx(10.11), ios(9.0), tvos(9.0), watchos(2.0))
int disconnectx(int, sae_associd_t, sae_connid_t);
#endif /* (!_POSIX_C_SOURCE || _DARWIN_C_SOURCE) */
__END_DECLS
其实不管是OC还是别的啥语言,这块提供的API都是差不多的,顶多有语法的区别。
上面这一段socket 的函数,我刚开始也看不懂。但是在一天的学习之后,看了很多的运用场景,慢慢的知道了。具体的运用场景涉及版权,不说了。
socket的基本操作
既然socket是“open—write/read—close”模式的一种实现,
那么socket就提供了这些操作对应的函数接口。
下面以TCP为例,介绍几个基本的socket接口函数。
Socket通信原理里面写了具体的函数,只是没有贴实际使用的demo。
总结:
- 知道了socket是什么
- 在OC中怎么创建UDP_socket对象
int socket_fd = socket(AF_INET, SOCK_DGRAM, IPPROTO_UDP);
struct sockaddr_in serv_addr;
memset(&serv_addr, '0', sizeof(serv_addr));
serv_addr.sin_family = AF_INET;
serv_addr.sin_addr.s_addr = inet_addr("192.168.0.1");
serv_addr.sin_port = htons(8080);
bind(socket_fd, (struct sockaddr *)&serv_addr, sizeof(serv_addr));
3.socket 和fd的关系(这里没有细讲)
4.在这里记录了学习过程,哈哈
网友评论