现在的位置: 首页 > 综合 > 正文

C++实现UDP和TCP通信(windows)

2018年01月24日 ⁄ 综合 ⁄ 共 3486字 ⁄ 字号 评论关闭

1.TCP与UDP的概念

TCP:Transmission Control Protocol 传输控制协议;

UDP:Transmission Control Protocol 传输控制协议。

具体概念在此就不赘述。

2.TCP与UDP的创建流程

a)UDP Server创建流程:  

WSAStartup(...)->socket(...)->bind(...)->recvfrom(...)->closesocket(...)->WSACleanup();   

   UDP Client创建流程: 

WSAStartup(...)->socket(...)->sendto(...)->closesocket(...)->WSACleanup();

b)TCP Server创建流程: 

WSAStartup(...)->socket(...)->bind(...)->listen(...)->accept(...)->recv(...)->closesocket(...)->    WSACleanup(); 
    TCP Client创建流程: 
WSAStartup(...)->socket(...)->bind(...)->connect(...)->send(...)->closesocket(...)->    WSACleanup();

函数解释:

  ①int WSAStartup(WORD wVersionRequested, LPWSADATA lpWSAData );本函数初始化winsock库

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)。

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类型。

参考:SOCKET编程中的三种地址

sockaddr_in mycomputerinfo; 
mycomputerinfo.sin_family=AF_INET; 
mycomputerinfo.sin_port=htons(端口号) //服务端端口,这里要用htons函数将端口从本地字节序转换为网络字节序才能使用。具体参见http://baike.baidu.com/view/569197.htm 
mycomputerinfo.sin_addr.s_addr=inet_addr(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:缓冲区长度。flags:调用执行方式

  ⑨int sendto( SOCKET s, const char FAR* buf, int len, int flags,const struct sockaddr FAR* to, int tolen); //该函数用于客户端。  
s:一个标识套接口的描述字。   buf:包含待发送数据的缓冲区。   len:buf缓冲区中数据的长度。   flags:调用方式标志位。   to:(可选)指针,指向目的套接口的地址。   tolen:to所指地址的长度。

   ⑩  int recvfrom(SOCKET s,void *buf,int len,unsigned int flags, struct sockaddr *from,int *fromlen);  //该函数用于客户端。  
s:标识一个已连接套接口的描述字。   buf:接收数据缓冲区。   len:缓冲区长度。   flags:调用操作方式。   from:(可选)指针,指向装有源地址的缓冲区。   fromlen:(可选)指针,指向from缓冲区长度值。

   ⑾ int closesocket( SOCKET s);//关闭套接字。

   ⑿int WSACleanup ( void );//中止Windows Sockets DLL的使用。 

3.TCP与UDP的C++实现

运行环境:VS2010

主要代码:UDP类、TCPServer类和TCPClient类

具体代码见:http://download.csdn.net/detail/lyphaian/6577381

参考资料:

http://www.cs.rutgers.edu/~pxk/rutgers/notes/sockets/

http://wenku.baidu.com/view/33774537eefdc8d376ee3251.html

http://www.oschina.net/code/snippet_193035_11668

http://blog.csdn.net/chpdirector84/article/details/4507685

抱歉!评论已关闭.