基本TCP套接字编程总结

1.分配一个套接口的描述字及其所用的资源

int socket(int family,int type, int protocol);
//family指定协议族
//type指定套接字类型
//protocol指定为某个协议常数值
 
 
  • 1
  • 2
  • 3
  • 4
  • 1
  • 2
  • 3
  • 4
family 选项
AF_INET IPv4协议
AF——INET6 IPv6套接字
AF_LOCAL Unix域协议
AF_ROUTE 路由套接字
AF_KEY 密钥套接字
type 选项
SOCK_STREAM 字节流套接字
SOCK_DGRAM 数据报套接字
SOCK_SEQPACKET 有序分组套接字
SOCK_RAW 原始套接字
protocol 选项
IPPROTO_TCP TCP传输协议
IPPROTO_UDP UDP传输协议
IPPROTO_SCTP SCTP传输协议

2.把本地协议地址给与一个套接字

int bind( int sockfd , const struct sockaddr * my_addr, socklen_t addrlen);
//sockfd是你创建的这个套接字
//my_addr是一个 指向一个特定协议的地址结构 的指针
//addrlen是该地址结构的长度
 
 
  • 1
  • 2
  • 3
  • 4
  • 1
  • 2
  • 3
  • 4

bind函数可以指定端口号或者IP,或者两个都指定,也可以都不指定 
端口对于bind
j没有绑定端口,以后客户端执行connect或者服务端执行listen时候,内核会指定特定的端口。让内核给客户程序选择端口算正常,但是这样一个”随意的端口”对于服务器很糟糕,因为服务器是通过他们自己有名的端口来工作的。 
IP对于bind : 
绑定IP,对于客户程序,相当于在该套接字上发送的IP数据报指定源IP地址。对于服务器程序,相当于值接收那些以该IP为目的地址的连接请求。不绑定IP,对于客户程序,根据外出网络接口选择源IP,如果是服务器程序,内核把客户程序发送的SYN的目的地值IP作为服务器源地址IP。

由于bind第二个参数是const类型,因此在没有指定端口情况下,内核也没有办法通过bind函数返回端口值,为了得到这个临时端口值,要用getsockname函数来得到协议地址:

int getsockname(int sockfd, struct sockaddr *localaddr, socklen_t *addrlen);

 
 
  • 1
  • 2
  • 1
  • 2

3.把套接字转换成被动套接字,并且为内核规定相应套接字排队的最大排队数。

int listen(int sockfd, int backlog);
//sockfd是要被转换的主动套接字
//backlog是最大排队数
/*对于backlog,它是未连接队列和已连接队列的。在未连接队列的套接字还没有进行完三次握手,处于SYN_RCVD状态,套接字在未连接一项中存在时间越为一个RTT。在已连接队列的套接字处于ESTABLISHED状态。
*/
 
 
  • 1
  • 2
  • 3
  • 4
  • 5
  • 1
  • 2
  • 3
  • 4
  • 5

4 开始接纳客户请求。

int accept(int sockfd, struct sockaddr *addr, socklen_t *addrlen);
//返回值是一个全新的,已连接套接字描述符,会包含客户端的IP和端口。用户进程的协议地址和协议大小,可以用NULL代替。
 
 
  • 1
  • 2
  • 1
  • 2

5 TCP客户端在socket之后会建立和TCP服务器的连接

 int connect(int s, const struct sockaddr * name, int namelen);
 
 
  • 1
  • 1

客户在调用connect前不必要调用bind函数,内核会确定源IP地址和临时端口。 
connect会激发TCP三次握手的第一次,即客户程序发送SYN请求,服务器程序会在accept时候给客户端发送SYN和ACK,即第二次握手。 
connect调用失败的原因如下
1.TCP客户程序没有受到SYN分节的相应,返回ETIMEDOUT错误标识。 
2.对客户程序的SYN相应RST,表明服务端指定端口没有进程在等待与客户程序连接,返回ECONNREFUSED错误标识。 
3.客户发出的SYN在路由过程中产生路由不可达并返回给客户,客户在一定事件之后返回EHOSTUNREACH或者ENETUNREACH标识。

6.万事大吉,开始收工。

int close(int sockfd); 
 
 
  • 1
  • 1

close默认操作是把sockfd标记成已关闭,然后立刻返回到调用进程。并且调用进程不能再使用这个表述符。

  • 1
    点赞
  • 1
    收藏
    觉得还不错? 一键收藏
  • 1
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论 1
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值