网络编程 C++ ———WinSock
2012-04-22 00:09
169 查看
网络编程 C++ ———WinSock
Windows Socket (即Winsock)以U.C. Berkeley大学BSD UNIX中流行的Socket接口为范例定义了一套microsoft Windows下网络编程接口。它不仅包含了人们所熟悉的Berkeley Socket风格的库函数;也包含了一组针对Windows的扩展库函数,以使程序员能充分地利用Windows消息驱动机制进行编程。
通信的基础是套接口(Socket),一个套接口是通讯的一端。包含5种信息:
本地协议端口
本地主机地址
远程协议端口
远程主机地址
协议 (程序在网络上传输数据是使用的协议)
套接字分类:
流式套接字 (SOCK_STREAM)
提供了双向、有序的、无重复的以及无记录边界的数据流服务,适合处理大量数据。它是面向联结的,必须建立数据传输链路,同时还必须对传输的数据进行验证, 确保数据的准确性。因此,系统开销较大。
数据报套接字 (SOCK_DGRAM)
数据报套接字也支持双向的数据流,但不保证传输数据的准确性,但保留了记录边界。由于数据报套接字是无联接的,例如广播时的联接,所以并不保证接收端是否正在侦听。数据报套接字传输效率比较高。
原始套接字 (SOCK_RAW)
原始套接字保存了数据包中的完整IP头,前面两种套接字只能收到用户数据。因此可以通过原始套接字对数据进行分析。支持更底层的协议 ,多用于实验新的协议和抓包嗅探。
套接字结构体:
主机地址结构体:
h_name为主机名字。
h_aliases为主机别名列表。
h_addrtype为地址类型。
h_length为地址类型。
h_addr_list为IP地址,如果该主机有多个网卡,就包括地址的列表。
数据类型的基本定义:
typedef unsigned char u_char;
typedef unsigned short u_short;
typedef unsigned int u_int;
typedef unsigned long u_long;
几个常用的字节(网络 与主机)转换函数:
unsigned long inet_addr(const char FAR * cp )
用法: unsigned long addr=inet_addr("192.1.8.84")
u_short ntohs(u_short nPort ) network to host short
u_short htons(u_short nPort )
u_long htonl(u_long nAddr)
u_long
ntohl(u_long nAddr)
WinSock 编程需要包含头文件Winsock2.0 和库文件WS2_32.LIB 和动态库WS2_32.DLL。在使用其库函数之前必须加载套接字库。
int WSAStartup ( WORD wVersionRequested, LPWSADATA lpWSAData );wVersionRequested
wVersionRequested:一个WORD(双字节)型数值,指定了应用程序需要使用的Winsock规范的最高版本。
lpWSAData 指向WSADATA数据结构的指针,用来接收Windows Sockets实现的细节。
在应用程序关闭套接字之后,应该调用WSACleanUp()终止Winsock DLL的调用,释放资源,以备下一次使用。
Winsock API
SOCKET socket(int af,int type,int protocol)
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 )
int send(SOCKET s, const char FAR * buf, int len, int flags )
int recv( SOCKET s, char FAR * buf, int len, int flags )
int shutdown(SOCKET s, int how)
int closesocket( SOCKET s )
int getsockopt(SOCKET s, int level, int optname, char FAR * optval, int FAR * optlen)
读取socket属性,s为欲读取属性的套接字。level为套接字选项的级别,大多数是特定协议和套接字专有的。如IP协议应为 IPPROTO_IP。
optname为读取选项的名称
optval为存放选项值的缓冲区指针。
optlen为缓冲区的长度
用法:
int ttl=0; //读取TTL值
int rc = getsockopt( s, IPPROTO_IP, IP_TTL, (char *)&ttl, sizeof(ttl));
int setsockopt(SOCKET s,int level, int optname,const char FAR * optval, int optlen)
设置socket属性,s为欲设置属性的套接字。
level为套接字选项的级别,用法同上。
optname为设置选项的名称
optval为存放选项值的缓冲区指针。
optlen为缓冲区的长度
用法:
int ttl=32; //设置TTL值
int rc = setsockopt( s, IPPROTO_IP, IP_TTL, (char *)&ttl, sizeof(ttl));
流式套接字编程模型:
数据报套接字编程模型:
WinSock的TCP通信 例子程序(VC++6.0 实现):
Windows Socket (即Winsock)以U.C. Berkeley大学BSD UNIX中流行的Socket接口为范例定义了一套microsoft Windows下网络编程接口。它不仅包含了人们所熟悉的Berkeley Socket风格的库函数;也包含了一组针对Windows的扩展库函数,以使程序员能充分地利用Windows消息驱动机制进行编程。
通信的基础是套接口(Socket),一个套接口是通讯的一端。包含5种信息:
本地协议端口
本地主机地址
远程协议端口
远程主机地址
协议 (程序在网络上传输数据是使用的协议)
套接字分类:
流式套接字 (SOCK_STREAM)
提供了双向、有序的、无重复的以及无记录边界的数据流服务,适合处理大量数据。它是面向联结的,必须建立数据传输链路,同时还必须对传输的数据进行验证, 确保数据的准确性。因此,系统开销较大。
数据报套接字 (SOCK_DGRAM)
数据报套接字也支持双向的数据流,但不保证传输数据的准确性,但保留了记录边界。由于数据报套接字是无联接的,例如广播时的联接,所以并不保证接收端是否正在侦听。数据报套接字传输效率比较高。
原始套接字 (SOCK_RAW)
原始套接字保存了数据包中的完整IP头,前面两种套接字只能收到用户数据。因此可以通过原始套接字对数据进行分析。支持更底层的协议 ,多用于实验新的协议和抓包嗅探。
套接字结构体:
struct sockaddr { u_short sa_family; /* address family */ char sa_data[14]; /* up to 14 bytes of direct address */ };该结构体地址为通用Socket地址结构 。sa_family 可以选择不同的通信域。 下面的sockaddr_in则是专门针对Internet域的Socket地址结构体。
struct in_addr { union { struct { u_char s_b1,s_b2,s_b3,s_b4; } S_un_b; struct { u_short s_w1,s_w2; } S_un_w; u_long S_addr; } S_un;
主机地址结构体:
struct hostent { char FAR * h_name; /* official name of host */ char FAR * FAR * h_aliases; /* alias list */ short h_addrtype; /* host address type */ short h_length; /* length of address */ char FAR * FAR * h_addr_list; /* list of addresses */ #define h_addr h_addr_list[0] /* address, for backward compat */ };
h_name为主机名字。
h_aliases为主机别名列表。
h_addrtype为地址类型。
h_length为地址类型。
h_addr_list为IP地址,如果该主机有多个网卡,就包括地址的列表。
数据类型的基本定义:
typedef unsigned char u_char;
typedef unsigned short u_short;
typedef unsigned int u_int;
typedef unsigned long u_long;
几个常用的字节(网络 与主机)转换函数:
unsigned long inet_addr(const char FAR * cp )
用法: unsigned long addr=inet_addr("192.1.8.84")
u_short ntohs(u_short nPort ) network to host short
u_short htons(u_short nPort )
u_long htonl(u_long nAddr)
u_long
ntohl(u_long nAddr)
WinSock 编程需要包含头文件Winsock2.0 和库文件WS2_32.LIB 和动态库WS2_32.DLL。在使用其库函数之前必须加载套接字库。
int WSAStartup ( WORD wVersionRequested, LPWSADATA lpWSAData );wVersionRequested
wVersionRequested:一个WORD(双字节)型数值,指定了应用程序需要使用的Winsock规范的最高版本。
lpWSAData 指向WSADATA数据结构的指针,用来接收Windows Sockets实现的细节。
在应用程序关闭套接字之后,应该调用WSACleanUp()终止Winsock DLL的调用,释放资源,以备下一次使用。
Winsock API
SOCKET socket(int af,int type,int protocol)
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 )
int send(SOCKET s, const char FAR * buf, int len, int flags )
int recv( SOCKET s, char FAR * buf, int len, int flags )
int shutdown(SOCKET s, int how)
int closesocket( SOCKET s )
int getsockopt(SOCKET s, int level, int optname, char FAR * optval, int FAR * optlen)
读取socket属性,s为欲读取属性的套接字。level为套接字选项的级别,大多数是特定协议和套接字专有的。如IP协议应为 IPPROTO_IP。
optname为读取选项的名称
optval为存放选项值的缓冲区指针。
optlen为缓冲区的长度
用法:
int ttl=0; //读取TTL值
int rc = getsockopt( s, IPPROTO_IP, IP_TTL, (char *)&ttl, sizeof(ttl));
int setsockopt(SOCKET s,int level, int optname,const char FAR * optval, int optlen)
设置socket属性,s为欲设置属性的套接字。
level为套接字选项的级别,用法同上。
optname为设置选项的名称
optval为存放选项值的缓冲区指针。
optlen为缓冲区的长度
用法:
int ttl=32; //设置TTL值
int rc = setsockopt( s, IPPROTO_IP, IP_TTL, (char *)&ttl, sizeof(ttl));
流式套接字编程模型:
数据报套接字编程模型:
WinSock的TCP通信 例子程序(VC++6.0 实现):
//TCPSrv #include <stdio.h> #include <winsock2.h> #pragma comment (lib,"WS2_32.lib") int InitSock(BYTE minorVer=2,BYTE majorVer=2) { WSADATA wsadata; WORD sockVersion=MAKEWORD(minorVer,majorVer); if(::WSAStartup(sockVersion,&wsadata)!=0) { printf("failed WSAStarUp() "); return 0; } return 1; } void UnInitSock() { ::WSACleanup(); } int main() { if(!InitSock()) return 0; SOCKET sListen=::socket (AF_INET,SOCK_STREAM,IPPROTO_IP); if(sListen==INVALID_SOCKET) { printf("failed socket()"); return 0; } // 填充地址结构体 sockaddr_in sAddr; sAddr.sin_family=AF_INET; sAddr.sin_port=htons(7565); sAddr.sin_addr.S_un.S_addr=INADDR_ANY; if(::bind (sListen,(LPSOCKADDR)&sAddr,sizeof(sAddr))==SOCKET_ERROR) { printf("failed bind()"); return 0; } if(::listen (sListen,2)==SOCKET_ERROR) { printf("failed listen()"); return 0; } sockaddr_in cAddr; int nAddrLen=sizeof(cAddr); SOCKET sClient; char szText[]="TCP Server Demo! \r\n"; while(TRUE) { sClient=::accept(sListen,(SOCKADDR*)&cAddr,&nAddrLen); if(sClient==INVALID_SOCKET) { printf("failed accpet()"); continue; } printf("½ÓÊÕµ½Ò»¸öÁ¬½Ó£º%s \r\n",inet_ntoa(cAddr.sin_addr)); ::send(sClient,szText,strlen(szText),0); ::closesocket(sClient); } ::closesocket(sListen); UnInitSock(); return 0; }
//TCPClient #include <stdio.h> #include <winsock2.h> #pragma comment (lib,"WS2_32.lib") int InitSock(BYTE minorVer=2,BYTE majorVer=2) { WSADATA wsadata; WORD sockVersion=MAKEWORD(minorVer,majorVer); if(::WSAStartup(sockVersion,&wsadata)!=0) { printf("failed WSAStarUp() "); return 0; } return 1; } void UnInitSock() { ::WSACleanup(); } int main() { if(!InitSock()) return 0; SOCKET s=::socket (AF_INET,SOCK_STREAM,IPPROTO_TCP); if(s==INVALID_SOCKET) { printf("failed socket()"); return 0; } sockaddr_in servAddr; servAddr.sin_family=AF_INET; servAddr.sin_port=htons(7565); servAddr.sin_addr.S_un.S_addr=inet_addr("127.0.0.1"); //ÔÚ±¾»ú²âÊÔ £¬ÔÚÁ½Ì¨²»Í¬»úÆ÷ÔÚʹÓÃÏìÓ¦µÄIpµØÖ·¼´¿É if(::connect(s,(sockaddr*)&servAddr,sizeof(servAddr))==-1) { printf("failed connect()"); return 0; } char buff[256]; int nRecv=::recv(s,buff,256,0); if(nRecv>0) { buff[nRecv]='\0'; printf("接收到数据%s",buff); } ::closesocket(s); UnInitSock(); return 0; }
相关文章推荐
- 用C++实现网络爬虫技术(WinSock编程)
- C++网络编程--简单的WinSock代码
- C++网络编程
- 利用WinSock实现简单网络编程
- C++ 用libcurl库进行http 网络通讯编程
- 什么是网络编程,Winsock ,SDK
- C++网络编程,明日之旅-CWSS
- c++基本网络编程实例
- Boost.Asio c++ 网络编程翻译(11)
- C++网络编程 ACE相关资料收集
- C++实现网络编程 服务端与客户端原代码
- windows编程--网络编程学习--winsock编程(2)
- 【转载】C++ 用libcurl库进行http通讯网络编程
- C++ 用libcurl库进行http通讯网络编程
- 网络编程 什么是Winsock
- C/C++网络编程中的TCP保活(转载)
- c++网络编程3:UDP编程
- C++ 用libcurl库进行http通讯网络编程
- C++网络编程之TCP UDP
- C++中Socket网络编程实例详解