❤️💕💕计算机网络--TCP/IP 学习。Myblog:http://nsddd.top
[TOC]
我们在进行套接字通信即使是不同的语言,不同的平台流程都是一样的,只是某些参数的类型有所区别。
套接字通信不同语言之间的流程都是一样的,但是不同的编程语言调用的接口可能是有所区别。越高级的语言调用流程就越是简单。
在 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 类型的变量,将地址传递给该函数的第二个参数
- wVersionRequested: 使用的 Windows Socket 的版本,一般使用的版本是 2.2
注销 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);