2024年4月28日发(作者:)
TCP/UDP通信编程入门(C++)
与UDP连接模式的比较
TCP:Transmission Control Protocol 传输控制协议TCP是一种面向连接(连接导向)的、可
靠的、基于字节流的运输层(Transport layer)通信协议.
UDP:User Datagram Protocol 用户数据报协议(UDP)是 OSI 参考模型中一种无连
接的传输层协议,提供面向事务的简单不可靠信息传送服务.
有关这两种模式如果你想了解更多的话,看这儿 :/?syn=TCP
/
a).TCP Server创建流程:
WSAStartup(...)->socket(...)->bind(...)->listen(...)->accept(...)->recv(...)->closesocket(...)->
WSACleanup();
TCP Client创建流程:
WSAStartup(...)->socket(...)->bind(...)->connect(...)->send(...)->closesocket(...)->
WSACleanup();
b).UDP Server创建流程:
WSAStartup(...)->socket(...)->bind(...)->recvfrom(...)->closesocket(...)->WSACleanup();
UDP Client创建流程:
WSAStartup(...)->socket(...)->sendto(...)->closesocket(...)->WSACleanup();
上面的不用记,等下面的函数讲解完,函数理解了,也就自然串起来了。
函数解析:
①int WSAStartup(WORD wVersionRequested, LPWSADATA lpWSAData );本函数初始化
winsock库
EG:
WSADATA wsa;
WSAStartup(MAKEWORD(2,2),&wsa);//MAKEWORD将前面的2和后面的2组成一个新的
WORD。生成一个版本号。MAKEWORD(a,b),a=2,1;b=1,0;都可以。当然你用
0x101,0x200,0x202也没错。
②SOCKET socket( int af, int type, int protocol );
第一个参数指定应用程序使用的通信协议的协议族,对于TCP/IP协议族,该参数置
AF_INET;
第二个参数指定要创建的套接字类型,流套接字类型为SOCK_STREAM、数据报套接字类
型为SOCK_DGRAM;
第三个参数指定应用程序所使用的通信协议。 如果协议protocol未指定(等于0),则使用
缺省的连接方式。(这个通常设置为0)。
EG:
socket(AF_INET,SOCK_STREAM,0);
③int bind( SOCKET s, const struct sockaddr FAR* name,int namelen);
sockaddr结构定义如下:struct sockaddr{
u_short sa_family;
char sa_data[14];
};
在使用这个函数之前,必须要对结构体sockaddr_in的结构变量初始化。struct sockaddr_in {
short int sin_family; /* Address family */
unsigned short int sin_port; /* Port number */
struct in_addr sin_addr; /* Internet address */
unsigned char sin_zero[8]; /* Same size as struct sockaddr */
//这个不用管,只是为了使结构体与sockaddr_in结构体长度匹
配.
};
这儿因为要绑定主机,所以必须用结构体sockaddr_in的结构变量记录主机信息。然后在强
制类型转换成sockaddr类型。应该不难理解吧~
EG:
sockaddr_in mycomputerinfo;
_family=AF_INET;
_port=htons(端口号) //服务端端口,这里要用htons函数将端口从本地字
节序转换为网络字节序才能使用。具体参见/view/
_addr.s_addr=inet_addr(IP); //服务端IP地址。对IP的初始化还有另外一种
方式。具体记不清了,自己查阅一下吧。inet_addr(...)函数将字符串转换为32位整数。因为
我们输入的IP地址是字符串,所以要转换的。
④int listen( SOCKET s, int backlog); //这个函数没什么要讲的。最后一个参数是等待连接对列
的最大 长度。
⑤SOCKET accept( SOCKET s, struct sockaddr FAR* addr,int FAR* addrlen);
这个函数用于服务端,进行通信连接用的。
注意喽,这儿是个重点。对于TCP连接来说,有两个套接字,一个监听套接字,一个会话
套接字。 在这个函数之前使用的套接字为监听套接字,在这个函数及之后使用的套接字则
为会话套接字。
再讲讲这两个套接字的运行过程,我们首先是定义了一个监听套接字使用函数 listen(...)
去监听来自客户端的连接请求,当我们的监听套接字接收到连接请求,把连接请求传递给会
话套接字,然后在从消息队列中取出下一条消息,如果没有消息的话,则处于等待状态。而
accept(...)函数接收到连接请求后,则会建立起服务端与客户端的连接,为后面的通信做
准备。我这么说,你应该明白吧,很简单的。
⑥ int connect( SOCKET s, const struct sockaddr FAR* name, int namelen);
这个函数用于客户端,进行通信连接用的。
⑦int recv( SOCKET s, char FAR* buf, int len, int flags); //该函数用于服务端。
s:一个标识已连接套接口的描述字。 buf:用于接收数据的缓冲区。 len:缓冲区
长度。 flags:指定调用方式
⑧int send( SOCKET s, const char FAR* buf, int len, int flags); //该函数用于服务端。
s:一个标识已连接套接口的描述字。 buf:包含待发送数据的缓冲区。 len:缓冲区长度。


发布评论