Socket 其实是通过在 应用层和 传输层之间 建立一个Socket层的一个中间层,向下可以连接UDP,TCP,当然也可以用作本地进程间通信。
主要包括有
socket(int domain, int type, int protocol);
这里的domain 包含有挺多种的协议族,但我们主要用到两个,AF_UNIX一个是用于UNIX域协议,(文件系统套接字)
另外一个是AF_INET ARPA 因特网协议(UNIX 网络套接字)
type 指的是传输的方式,包括有流 和 数据包(SOCK_STREAM,SOCK_DGRAM),前者借助TCP实现,后者需要UDP实现。就是是否为有链接的服务。
而后者是悬着到底使用什么协议通信,这个一般置零,表示默认通信方式。
套接字有套接字的地址格式。对于 AF_UNIX,和AF_INET 这两者的格式有些不同,注意需要引入不同的库(sys/un.h, netinet/in.h)
struct sockaddr_un{
sa_family sun_family;char sun_path[];
}
sturct sockaddr_in{
short int sin_family;
unsigned short int sin_port;
struct in_addr sin_addr;
};
其中
struct in_addr sin addr 结构如下:
struct in_addr{
unsigned long int s_addr;};
注意
1.这里用的是IPv4的地址,如果是IPv6,则会有所不同。
2.还有建议对地址在使用之前首先置零清空,然后再使用,因为在实际编程中,出过一些挺奇怪的情况。
int bind (int socket, const struct sockaddr* address, size_t address_len);
前者是当前该身份 即server/client 的 通过socket函数 获得的一个状态描述
address指的是需要关联的文件系统路径名 或者是IP端口号,
最后的是长度,一般sizeof前面的那个address就好啦。
在client的时候其实可以通过 client_addr.sin_port=htons(0)让系统自动分配一个空闲的端口号。就不需要关联也可以的。
int connect(int socket, const struct sockaddr* address, size_t address_len);
这里的connect参数看起来和bind一模一样,但是注意后两者是你要连接到的目标机的address及其长度。
发起连接的一般为client。
----------------------------下面的一般是作server才会调用的。-----------------------------------------
int listen(int socket, int backlog);
这里的后者是指定套接字队列的最大长度,也就是说允许有多少等待处理的client连接。
int accept(int socket,struct sockaddr* address, size_t address_len);
后两者的是client的address,当然这时候我们是不清楚client的address,不过空设一个参数,把address接回来。
在client 和 server 之间的信息传输 我们可以使用 recv() send()
当然 网络I/O的可以有挺多的函数
- read()/write()
- recv()/send()
- readv()/writev()
- recvmsg()/sendmsg()
- recvfrom()/sendto()

295

被折叠的 条评论
为什么被折叠?



