基本TCP套接字编程

Posted

tags:

篇首语:本文由小常识网(cha138.com)小编为大家整理,主要介绍了基本TCP套接字编程相关的知识,希望对你有一定的参考价值。

socket函数原型:

#include<sys/socket.h>
int socket(int family, int type, int protocol);//执行成功则返回非负的套接字描述符;出错则返回-1

socket函数用来打开一个(主动)套接字。在该函数中需要指定所使用的协议族(family)、套接字类型(type)、使用的协议(protocol)。


协议族的一般取值:

family协议族的说明
AF_INETIPv4协议
AF_INET6IPv6协议
AF_LOCALUnix域协议
AF_ROUTE路由套接字协议
AF_KEY密钥套接字


套接字类型:


type说明
SOCK_STREAM字节流套接字
SOCK_DGRAM数据报套接字
SOCK_SEQPACKET有序分组套接字
SOCK_RAM原始套接字


协议:


protocol说明
IPPROTO_CPTCP传输协议
IPPROTO_UDPUDP传输协议
IPPROTO_SCTPSCTP传输协议


socket函数中family和type参数组合


AF_INETAF_INET6AF_LOCALAF_ROUTEAF_KEY
SOCK_STREAMTCP|SCTPTCP|SCTP

SOCK_DGRAMUDPUPD

SOCK_SEQPACKETSCTPSCTP

SOCK_RAMIPv4IPv6



connect函数

TCP客户端通过connect函数建立与TCP服务器的连接。

#include<sys/socket.h>
int connect(int sockfd, const struct sockaddr *servaddr, socklen_t addrlen);//成功则返回0,失败则返回-1

参数介绍:

  sockfd--由socket闯将的主动套接字。

  servaddr--指向套接字地址结构的指针。

  socklen--套接字结构的大小


该函数的作用是建立与服务器端的连接,所以,在套接字中一定要包含服务器的IP地址和端口号。若使用TCP套接字(type选择SOCK_STREAM),则该函数会激发TCP连接的三次握手,而且在调用该函数时,会阻塞进程,直到该函数执行成功或失败时才继续向下进行。在该函数出错返回时,可能有以下几种情况:

  1.TCP客户端没有收到来自服务器端的SYN分节的相应,返回ETIMEDOUT错误。

  2.TCP服务器端对TCP客户端的SYN分节的响应是RST(表示复位),则表示该服务器主机在我们指定的端口上没有进程在等待与之连接(可能是达到最大线程,或者服务器进程没有运行)。客户端收到RST后马上会返回ECONNREFUSED错误。

 3.若客户端发出的SYN分节在中转路由上引发了"destination unreachable"(目的地不可达)ICMP错误,客户机将继续发送SYN分节,直到超过规定时间。


ps://RST是TCP首部6大标志位之一,表示重置连接。至于什么是重置连接,之后给出解释。


bind函数

bind函数把一个本地协议地址赋予一个套接字。对于网际协议,协议地址是IP地址(ipv4/ipv6)与端口号(tcp/udp)的组合。

#include<sys/socket.h>
int bind(int sockfd, const sockaddr *myaddr, socklen_t addlen);//执行成功返回0,出错返回-1.

sockfd:通过socket打开的套接字描述符

myaddr:指向特定于协议的套接字地址结构的指针

addlen:地址结构的长度。

该函数执行成功后,套接字里就含有上述一个协议地址。


listen函数

listen函数把一个未连接的套接字转化为一个被动套接字,指示内核应该接受指向该套接字的连接请求。

#include<sys/socket.h>
int listen(int sockfd, int backlog);//执行成功返回0,失败返回-1;

sockfd:表示主动套接字;backlog表示最大连接数

ps://最大连接数包括已完成连接和未完成连接。关于该函数的一些详细讨论在《Unix网络编程:卷一》中有详细讲解,此处不作说明。


accept函数

accept函数用于从已完成连接队列的队头获得下一个已完成连接,倘若队列为空,该函数将进入睡眠模式(阻塞状态)。

#include<sys/socket.h>
int accept(int sockfd, struct sockaddr *cliaddr, socklen_t *addrlen);//执行成功返回非负的套接字描述符,失败返回-1;

这个函数的特殊之处在于第三个参数,是一个指针,也就就是说该形参的值可以在函数中改变。这个参数被称作"值 -- 结果"参数。该函数执行以前,形参所指的是套接字地址结构的长度,执行之后,形参的值表示由内核存放在该套接字地址结构中的实际字节数。

在这里还有一个需要区分的概念:监听套接字和已连接套接字。listen执行之后的套接字称作监听套接字,用作该函数的第一个参数;accept函数执行之后的套接字叫做已连接套接字。监听套接字是有服务器进程使用的,在服务器的生命周期内一直存在;已连接套接字是内核为服务器创建的,在一次服务完成后,相应的已连接套接字就会被关闭。


close函数

close函数用来关闭一个套接字,关闭之后的套接字将不能再被使用。

#include<sys/socket.h>
int close(int sockfd);//执行成功返回0,失败返回-1


本文出自 “execute” 博客,请务必保留此出处http://executer.blog.51cto.com/10404661/1775267

以上是关于基本TCP套接字编程的主要内容,如果未能解决你的问题,请参考以下文章

基本的TCP套接字编程

基本TCP套接字编程

基本套接字编程 -- tcp篇

C/C++ 网络编程4: 基本TCP套接字编程

基本TCP套接字编程

第4章 基本tcp套接字编程