tcp/udp socket连接

快要放假了,不怎么想工作,写写博客。这两天简单看了一些socket的相关知识,做下总结。
一、socket介绍
套接字描述符,是通信端点的抽象。一开始时学习socket只认为可以用在网络通信上,这次才发现也可以用在本地中,可以作为进程间通信来使用。只是在建立socket上一些常量做下改变就可以了。
首先创建socket的函数有socket()和socketpair();

int socket(int domain, int type, int protocol);

这里的domain和type有不同的选择,创建的socket也不同。
这里写图片描述
(当然还有其他类型,可以自己查阅)
域名为PF_INET和PF_UNIX (其中对于BSD,是AF,对于POSIX是PF),type是流类型tcp和数据报udp。
对于本地的socket建立一般可以使用socketpair()

int socketpair(int d, int type, int protocol, int sv[2]); 

socketpair()函数建立一对匿名的已经连接的套接字,其特性由协议族d、类型type、协议protocol决定,建立的两个套接字描述符会放在sv[0]和sv[1]中。
第1个参数d,表示协议族,只能为AF_LOCAL或者AF_UNIX;
第2个参数type,表示类型,只能为0。
第3个参数protocol,表示协议,可以是SOCK_STREAM或者SOCK_DGRAM。用SOCK_STREAM建立的套接字对是管道流,与一般的管道相区别的是,套接字对建立的通道是双向的,即每一端都可以进行读写。

二、寻址
当建立好socket后,接下来的工作就是明确本地的地址,对于主动连接的那一端来说还多一个要连接的目的端地址。这个地址是放在一个结构体里的 struct sockaddr。

struct sockaddr {
    unsigned short sa_family; 
    char sa_data[14]; 
};

套接字实现可以自由的添加额外的成员并且定义sa_data成员大小。
在linux下

struct sockaddr {
    sa_family_t sa_family; 
    char sa_data[14]; 
};

因特网地址定义在

struct sockaddr_in {
    short int sin_family; 
    unsigned short int sin_port; 
    struct in_addr sin_addr;
    unsigned char sin_zero[8]; 
};

三、相关函数
当上述的socket和地址都确定好之后,就开始将他们两绑定用bind()函数;

int bind(int sockfd,const struct sockaddr* myaddr,socklen_t addrlen)

当socket函数返回一个描述符时,只是存在于其协议族的空间中,并没有分配一个具体的协议地址(这里指IPv4/IPv6和端口号的组合),bind函数可以将一组固定的地址绑定到sockfd上。
1、

int listen(int sockfd,int backlog)

这里写图片描述
udp没有此函数。
2、

int connect(int sockfd,conststruct sockaddr *addr, socklen_t addrlen)

通过此函数建立于TCP服务器的连接,实际是发起三次握手过程,仅在连接成功或失败后返回。参数sockfd是本地描述符,addr为服务器地址,addrlen是socket地址长度。

UDP的connect函数,结果与tcp调用不相同,没有三次握手过程。内核只是记录对方的ip和端口号,他们包含在传递给connect的套接口地址结构中,并立即返回给调用进程。
3、

 accept

intaccept(int sockfd, struct sockaddr *addr, socklen_t *addrlen)

这里写图片描述

4、
ssize_t send(int sockfd,constvoid *buf, size_t len,int flags)

5、

ssize_t sendto(int sockfd,const void *buf, size_t len, int flags,const struct sockaddr *dst_addr, socklen_t addrlen);

6、

ssize_t recv(int sockfd,void *buf, size_t len,int flags)

其中:
sockfd:接收端套接字描述符;
buf:指定缓冲区地址,用于存储接收数据;
len:指定的用于接收数据的缓冲区长度;
flags:一般指定为0
表示从接收缓冲区拷贝数据。成功时,返回拷贝的字节数,失败返回-1。阻塞模式下,recv/recvfrom将会阻塞到缓冲区里至少有一个字节(TCP)/至少有一个完整的UDP数据报才返回,没有数据时处于休眠状态。若非阻塞,则立即返回,有数据则返回拷贝的数据大小,否则返回错误-1,置错误码为EWOULDBLOCK。
7、

ssize_t recvfrom(int sockfd,void *buf, size_t len, int flags,struct sockaddr *src_addr, socklen_t *addrlen)
   sockfd:接收端套接字描述
   buf:用于接收数据的应用缓冲区地址
   len:指名缓冲区大小
   flags:通常为0
   src_addr:数据来源端的地址
   addrlen:src_addr地址的长度

注意后两个参数是输出参数,其中addrlen既是输入又是输出参数,即值-结果参数,需要在调用时,指明src_addr的长度。另外,如果不关心数据发送端的地址,可以将后两者均设置为NULL。
8. close

close缺省功能是将套接字作“已关闭”标记,并立即返回到调用进程,该套接字描述符不能再为该进程所用:即不能作为read和write(send和recv)的参数,但是TCP将试着发送发送缓冲区内已排队待发的数据,然后按正常的TCP连接终止序列进行操作(断开连接4次握手-以FIN为首的4个TCP分节)。

  1. shutdown

shutdown不仅可以灵活控制关闭连接的读、写或读写功能,而且会立即执行相应的断开动作(发送终止连接的FIN分节等),此时不论有多少进程共享此套接字描述符,都将不能再进行收发数据。

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值