基本的TCP套接字编程
Posted fantasy_linux
tags:
篇首语:本文由小常识网(cha138.com)小编为大家整理,主要介绍了基本的TCP套接字编程相关的知识,希望对你有一定的参考价值。
上图基本展示了TCP客户端与服务器编程的基本的流程。
1、面向连接编程(TCP)
面向连接的网络应用程序开发流程比较固定,需要开发者创建服务器与客户端两个应用程序,通过网络是想进程间的通讯。
● 服务器端流程
1 创建套接字(socket)
2 服务绑定(bind)
3 服务侦听(listen)
4 处理新到连接(accept)
5 数据收发(recv\\send)
6 套接字关闭(close)
● 客户端流程
① 客户端套接字创建(socket)
② 发起连接(connect)
③ 数据发收(send\\recv)
④ 套接字关闭(close)
下面大致介绍下上述函数的一些基本的用法:
(1)socket函数:
函数原型:
int socket(int family,int type, int protocol);
socket()函数用于根据指定的地址族、数据类型和协议来分配一个套接口的描述字及其所用的资源。如果协议protocol未指定(等于0),则使用缺省的连接方式。 对于使用一给定地址族的某一特定套接口,只支持一种协议。但地址族可设为AF_UNSPEC(未指定),这样的话协议参数就要指定了。协议号特定于进行通讯的“通讯域”。
支持下述类型描述:
SOCK_STREAM 提供有序的、可靠的、双向的和基于连接的字节流,使用带外数据传送机制,为Internet地址族使用TCP。 SOCK_DGRAM 支持无连接的、不可靠的和使用固定大小(通常很小)缓冲区的数据报服务,为Internet地址族使用UDP。 SOCK_STREAM类型的套接口为全双向的字节流。对于流类套接口,在接收或发送数据前必需处于已连接状态。用connect()调用建立与另一套接口的连接,连接成功后,即可用send()和recv()传送数据。当会话结束后,调用close()。带外数据根据规定用send()和recv()来接收。 实现SOCK_STREAM类型套接口的通讯协议保证数据不会丢失也不会重复。如果终端协议有缓冲区空间,且数据不能在一定时间成功发送,则认为连接中断,其后续的调用也将以WSAETIMEOUT错误返回。 SOCK_DGRAM类型套接口允许使用sendto()和recvfrom()从任意端口发送或接收数据报。如果这样一个套接口用connect()与一个指定端口连接,则可用send()和recv()与该端口进行数据报的发送与接收。
(2)connect函数
函数原型:
int connect(intsockfd,const struct sockaddr *servaddr,socklen_t addrlen)
connect()用来将参数sockfd 的socket 连至参数serv_addr 指定的网络地址. 结构sockaddr请参考bind(). 参数addrlen 为sockaddr 的结构长度.
返回值:成功则返回0, 失败返回-1, 错误原因存于errno 中 。
(3)bind函数:
当一个套接字用socket()创建后,存在一个名字空间(地址族),但它没有被命名。bind()将套接字地址(包括本地主机地址和本地端口地址)与所创建的套接字号联系起来,即将名字赋予套接字,以指定本地半相关。其调用格式如下:
int PASCAL FAR bind(SOCKET s, const struct sockaddr FAR * name, int namelen);
参数s是由socket()调用返回的并且未作连接的套接字描述符(套接字号)。参数name是赋给套接字s的本地地址(名字),其长度可变,结构随通信域的不同而不同。
namelen表明了name的长度。
如果没有错误发生,bind()返回0。否则返回值SOCKET_ERROR。
地址在建立套接字通信过程中起着重要作用,作为一个网络应用程序设计者对套接字地址结构必须有明确认识。例如,UNIX有一组描述套接字地址的数据结构,其中使用TCP/IP
协议的地址结构为:
struct sockaddr_in{
short sin_family; /*AF_INET*/
u_short sin_port; /*16位端口号,网络字节顺序*/
struct in_addr sin_addr; /*32位IP地址,网络字节顺序*/
char sin_zero[8]; /*保留*/
}
(4)accept函数:
以上是关于基本的TCP套接字编程的主要内容,如果未能解决你的问题,请参考以下文章