总结
基于TCP(面向连接)的socket编程,分为服务器端和客户端
服务器端的流程如下:
(1)创建套接字(socket)
(2)将套接字绑定到一个本地地址和端口上(bind)
(3)将套接字设为监听模式,准备接收客户端请求(listen)
(4)等待客户请求到来;当请求到来后,接受连接请求,返回一个新的对应于此次连接的套接字(accept)
(5)用返回的套接字和客户端进行通信(send/recv)
(6)返回,等待另一个客户请求。
(7)关闭套接字。
客户端的流程如下:
(1)创建套接字(socket)
(2)向服务器发出连接请求(connect)
(3)和服务器端进行通信(send/recv)
(4)关闭套接字
操作函数
1、 socket:
创建socket 描述符
int socket(int domain, int type, int protocol);
domain=AF_INET,socket的类型,type=SOCK_STREAM 或SOCK_DGRAM,分别表示TCP连接和UDP连接;protocol=0。
返回一个整型socket描述符。
2.bind:
将socket描述符与你本机上的一个端口相关联(仅用于服务器)
int bind(int sockfd,struct sockaddr *my_addr, int addrlen);
Sockfd是一个socket描述符
my_addr是一个指向包含有本机IP地址及端口号等信息的sockaddr类型的指针;
addrlen=sizeof(struct sockaddr)。
返回:成功=0;失败=-1,errno=错误号。
可以用下面的赋值自动获得本机IP地址和随机获取一个没有被占用的端口号:
my_addr.sin_port = 0; /* 系统随机选择一个未被使用的端口号 */
my_addr.sin_addr.s_addr = INADDR_ANY; /* 填入本机IP地址 */
3.Connect:
与远端服务器建立一个TCP连接 (用于客户端)
int connect(int sockfd, struct sockaddr *serv_addr, int addrlen);
Sockfd是目的服务器的sockt描述符
serv_addr是包含目的机IP地址和端口号的指针。
返回:成功=0;失败=-1,errno=错误号。
4、Listen:
监听是否有服务请求 ,用于bind()后
int listen(int sockfd, int backlog);
Sockfd是Socket系统调用返回的socket 描述符;
backlog指定在请求队列中允许的最大请求数,缺省值为20。
返回:成功=0;失败=-1,errno=错误号。
5.accept:
接受来自客户的请求
int accept(int sockfd, void *addr, int *addrlen);
sockfd是被监听的socket描述符,
addr 是指向sockaddr_in变量的指针,存放客户主机的信息 ;
addrten 指向值为sizeof(struct sockaddr_in)的整型指针变量。
返回:成功返回一个新的socket描述符,来供这个新连接来使用。 错误发生时返回一个-1并且设置相应的errno值。
6.Send:
在连接(TCP)的socket方式下发送信息
int send(int sockfd, const void *msg, int len, int flags);
Sockfd是用来传输数据的socket描述符
msg是一个指向要发送数据的指针。
Len是以字节为单位的数据的长度。
flags一般情况下置为0。
7.recv:
在连接(TCP)的socket方式下接收数据
int recv(int sockfd,void *buf,int len,unsigned int flags);
Sockfd是接受数据的socket描述符;
buf 是存放接收数据的缓冲区;
len是缓冲的长度。
Flags也被置为0。
返回:实际上接收的字节数,如果连接中止,返回0,。出现错误时,返回-1并置相应的errno值。
8.sendto:
在在无连接(UDP)的socket方式下发送数据
int sendto(int sockfd, const void *msg,int len,unsigned int flags,const struct sockaddr *to, int tolen);
to表示目地机的IP地址和端口号信息
tolen=sizeof (struct sockaddr)。
返回:实际发送的数据字节长度或在出现发送错误时返回-1。
9.Recvfrom()
在无连接(UDP)的socket方式下接收数据
int recvfrom(int sockfd,void *buf,int len,unsigned int flags,struct sockaddr *from,int *fromlen);
from 保存源机的IP地址及端口号。
fromlen=sizeof(struct sockaddr)。
返回:实际存入from中的数据字节数。当出现错误时返回-1,并置相应的errno。
10.close()
释放socket,停止任何数据操作
close(sockfd);
11.shutdown:
单向关闭连接
int shutdown(int sockfd,int how);
how可以设为下列值:
·0-------不允许继续接收数据
·1-------不允许继续发送数据
·2-------不允许继续发送和接收数据,均为允许则调用close ()
shutdown在操作成功时返回0,在出现错误时返回-1(并置相应errno)。
12. gethostbyname:
域名和IP地址的转换
struct hostent *gethostbyname(const char *name);
13.inet_pton函数:
将点分十进制串转换成网络字节序二进制值,此函数对IPv4地址和IPv6地址都能处理。
int inet_pton(int family,const char * strptr,void * addrptr);
第一个参数可以是AF_INET或AF_INET6:第二个参数是一个指向点分十进制串的指针:第三个参数是一个指向转换后的网络字节序的二进制值的指针。
返回:1---成功 0---输入不是有效的表达格式 -1---失败
14.inet_ntop函数:
和inet_pton函数正好相反,inet_ntop函数是将网络字节序二进制值转换成点分十进制串。
const char * inet_ntop(int family,const void * addrptr,char * strptr,size_t len);
第一个参数可以是AF_INET或AF_INET6:第二个参数是一个指向网络字节序的二进制值的指针;第三个参数是一个指向转换后的点分十进制串的指针;第四个参数是目标的大小,以免函数溢出其调用者的缓冲区。
返回:指向结果的指针---成功 NULL---失败