Skip to content

Latest commit

 

History

History
187 lines (126 loc) · 4.75 KB

14.md

File metadata and controls

187 lines (126 loc) · 4.75 KB

第14节 win套接字通信

❤️💕💕计算机网络--TCP/IP 学习。Myblog:http://nsddd.top


[TOC]

window套接字通信

我们在进行套接字通信即使是不同的语言,不同的平台流程都是一样的,只是某些参数的类型有所区别。

套接字通信不同语言之间的流程都是一样的,但是不同的编程语言调用的接口可能是有所区别。越高级的语言调用流程就越是简单。

在 Window 中也提供了套接字通信的 API,这些 API 函数与 Linux 平台的 API 函数几乎相同,以至于很多人认为套接字通信的 API 函数库只有一套,下面来看一下这些 Windows 平台的套接字函数:

初始化套接字环境

使用 Windows 中的套接字函数需要额外包含对应的头文件以及加载响应的动态库:

include <winsock2.h>

//使用到的套接字库
ws2_32.dll

在 Windows 使用套接字需要先加载套接字库(套接字环境),最后需要释放套接字资源。

//初始化winsock库
/返回值,成功返回0,失败返回SOCKET_ERROR
WSAStartup(WORD wVersionRequested, LPWSADATA lpWSAData);
  • 参数:
    • wVersionRequested: 使用的 Windows Socket 的版本,一般使用的版本是 2.2
      • 初始化这个 MAKEWORD(2, 2); 参数
    • lpWSAData:一个 WSADATA 结构指针,这是一个传入参数
      • 创建一个 WSADATA 类型的变量,将地址传递给该函数的第二个参数

注销 Winsock 相关库,函数调用成功返回 0,失败返回 SOCKET_ERROR。

int WSACleanup (void);

使用举例:

WSAData wsa;

WSAStartup(MAKEWORD(2, 2), &wsa);

WSACleanup();

套接字通信函数

基于 Linux 的套接字通信流程是最全面的一套通信流程,如果是在某个框架中进行套接字通信,通信流程只会更简单,直接使用 window 的套接字 api 进行套接字通信,和 Linux 平台上的通信流程完全相同。

结构体

typedef struct in_addr {
  union {
  	struct{ unsigned char s_b1,s_b2, s_b3,s_b4;} S_un_b;
  	struct{ unsigned short s_w1, s_w2;} S_un_w;
  	unsigned long S_addr;	
  } S_un;
}IN_ADDR;

struct sockaddr_in {
  short int sin_family; 
  unsigned short int sin_port; 
  struct in_addr sin_addr; 
  unsigned char sin_zero[8]; 
};

typedef unsigned short  uint16_t;
typedef unsigned int    uint32_t;
typedef uint16_t in_port_t;
typedef uint32_t in_addr_t;
typedef unsigned short int sa_family_t;

struct in_addr
{
    in_addr_t s_addr;
};  

struct sockaddr_in
{
    sa_family_t sin_family;     
    in_port_t sin_port;         
    struct in_addr sin_addr;    
    
    unsigned char sin_zero[sizeof (struct sockaddr) - sizeof(sin_family) -
                      sizeof (in_port_t) - sizeof (struct in_addr)];
};

大小端转换函数

u_short htons (u_short hostshort );
u_long htonl ( u_long hostlong);


u_short ntohs (u_short netshort );
u_long ntohl ( u_long netlong);

// Linux函数,window上没有这两个函数
inet_ntop(); 
inet_pton();

unsigned long inet_addr (const char FAR * cp);	
in_addr_t     inet_addr (const char *cp);			

char* inet_ntoa(struct in_addr in);

套接字函数

window的api中套接字对应的类型是 SOCKET 类型, linux中是 int 类型, 本质是一样的
SOCKET socket(int af,int type,int protocal);
/*参数:
    - af: 地址族协议
        - ipv4: AF_INET (windows/linux)
        - PF_INET (windows)
        - AF_INET == PF_INET
   - type: 和linux一样
       	- SOCK_STREAM
        - SOCK_DGRAM
   - protocal: 一般写0 即可
       - 在windows上的另一种写法
           - IPPROTO_TCP, 使用指定的流式协议中的tcp协议
           - IPPROTO_UDP, 使用指定的报式协议中的udp协议
*/
int bind(SOCKET s,const struct sockaddr FAR* name, int namelen);

int listen(SOCKET s,int backlog);

SOCKET accept ( SOCKET s, struct sockaddr FAR* addr, int FAR* addrlen );

int connect (SOCKET s,const struct sockaddr FAR* name,int namelen );

::connect(sock, (struct sockaddr*)&addr, sizeof(addr));

int recv (SOCKET s,char FAR* buf,int len,int flags);

int send (SOCKET s,const char FAR * buf, int len,int flags);

int closesocket (SOCKET s);		

int recvfrom(SOCKET s,char FAR *buf,int len,int flags,
         struct sockaddr FAR *from,int FAR *fromlen);

int sendto(SOCKET s,const char FAR *buf,int len,int flags,
       const struct sockaddr FAR *to,int tolen);

END 链接