赞
踩
- 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 shortu_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; }
Copyright © 2003-2013 www.wpsshop.cn 版权所有,并保留所有权利。