socket编程常用函数解析

====================================================================================================================================

开发环境:windows

开发工具:VC6.0

=======================================================================================================


1.windows下网络编程初始化----WSAStartup函数

int WSAStartup ( WORD wVersionRequested, LPWSADATA lpWSAData );

(1)wVersionRequested:一个WORD(双字节)型数值,在最高版本的Windows Sockets支持调用者使用,高阶字节指定小版本(修订本)号,低位字节指定主版本号;

(2)lpWSAData 指向WSADATA数据结构的指针,用来接收Windows Sockets实现的细节。

为了在应用程序当中调用任何一个Winsock API函数,首先第一件事情就是必须通过WSAStartup函数完成对Winsock服务的初始化,因此需要调用WSAStartup函数。使用Socket的程序在使用Socket之前必须调用WSAStartup函数。

该函数的第一个参数指明程序请求使用的Socket版本,其中高位字节指明副版本、低位字节指明主版本;操作系统利用第二个参数返回请求的Socket的版本信息。当一个应用程序调用WSAStartup函数时,操作系统根据请求的Socket版本来搜索相应的Socket库,然后绑定找到的Socket库到该应用程序中。以后应用程序就可以调用所请求的Socket库中的其它Socket函数了。

下面是在socket编程中调用WSAStartup函数加载socket动态链接库(dll)的例子

// 加载socket动态链接库(dll)
	WORD wVersionRequested;
	WSADATA wsaData;	// 这结构是用于接收Wjndows Socket的结构信息的
	int err;
	 
	wVersionRequested = MAKEWORD( 1, 1 );	// 请求1.1版本的WinSock库
	 
	err = WSAStartup( wVersionRequested, &wsaData );
	if ( err != 0 ) {
		return -1;			// 返回值为零的时候是表示成功申请WSAStartup
	}
	 
	if ( LOBYTE( wsaData.wVersion ) != 1 ||	HIBYTE( wsaData.wVersion ) != 1 ) {
		// 检查这个低字节是不是1,高字节是不是1以确定是否我们所请求的1.1版本
		// 否则的话,调用WSACleanup()清除信息,结束函数
		WSACleanup( );
		return -1; 
	}

2.创建套接字socket结构体

SOCKET socket(  
		int af, 
		int type, 
		int protocol  
		);
// 第一个参数,指定地址簇(TCP/IP只能是AF_INET,也可写成PF_INET)
// 第二个,选择套接字的类型 SOCK_STREAM 使用TCP协议
//                          SOCK_DRAM   使用UDP协议
//第三个,特定地址家族相关协议(0为自动

套接字与本地地址绑定bind函数

int bind(
	SOCKET s, 
	const struct sockaddr* name, 
	int namelen
	);
// 第一个参数,指定需要绑定的套接字;
// 第二个参数,指定该套接字的本地地址信息,该地址结构会随所用的网络协议的不同而不同
// 第三个参数,指定该网络协议地址的长度
在TCP/IP会使用sockaddr_in结构体代替sockaddr结构体,方便代替地址信息

truct sockaddr_in{ 
	short sin_family; 
	unsigned short sin_port; 
	struct in_addr sin_addr; 
	har sin_zero[8];
	};
	//     sin_family表示地址族,对于IP地址,sin_family成员将一直是AF_INET。
	//     sin_port指定将要分配给套接字的端口。
	//     sin_addr给出套接字的主机IP地址,下面是in_addr结构体
struct in_addr {
<span style="white-space:pre">	</span>union {
         { 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;
};
	//     sin_zero[8]给出填充数,让sockaddr_in与sockaddr结构的长度一样。
	//     将IP地址指定为INADDR_ANY,允许套接字向任何分配给本地机器的IP地址发送或接收数据。
	//     如果想只让套接字使用多个IP中的一个地址,可指定实际地址,用inet_addr()函数。

3.基于TCP/IP协议socket编程常用函数

由于TCP/IP协议是一个面向连接的协议,需要客户端向服务器端发送请求,服务器接受请求建立连接后双方才可以实现通信

(1)监听函数listen

int listen(SOCKET s,  int backlog);
// 第一个参数指定需要设置的套接字,第二个参数为(等待连接队列的最大长度)

(2)客户端发出请求函数connect

      int connect( SOCKET s,  const struct sockaddr* name,  int namelen);  
    // 第一个参数:需要进行连接操作的套接字  
    // 第二个参数:设定所需要连接的地址信息  
    // 第三个参数:地址的长度 

(3)服务器端接收请求函数accept

	 SOCKET accept(  SOCKET s,  struct sockaddr* addr,  int* addrlen);
	// 第一个参数,接收一个处于监听状态下的套接字
	// 第二个参数,sockaddr用于保存客户端地址的信息
	// 第三个参数,用于指定这个地址的长度
	// 返回的是向与这个监听状态下的套接字通信的套接字
(4)发送数据函数send

	 int send( SOCKET s,  const char* buf,  int len,  int flags);
	// 第一个参数,需要发送信息的套接字,
	// 第二个参数,包含了需要被传送的数据,
	// 第三个参数是buffer的数据长度,
	// 第四个参数,一些传送参数的设置
(5)接收数据函数recv

	  int recv(  SOCKET s,  char* buf,  int len,  int flags);
	// 第一个参数,建立连接后的套接字,
	// 第二个参数,接收数据
	// 第三个参数,接收数据的长度,
	// 第四个参数,一些传送参数的设置
4.基于UDP协议socket编程函数

由于UDP协议是一个非连接的协议,并不需要向TCP/IP协议一样建立,可以直接进行通信

(1)发送数据函数sento

int sendto(
	SOCKET s,
	const char FAR *buf,            
	int len,
	int flags,                       
	const struct sockaddr FAR *to,
	int tolen 
	);
	//第一个参数,需要发送的数据的套接字
	//第二个参数,存储发送的数据的数组
	//第三个参数,发送数据的长度
	//第四个参数, 标志位,一般为0
	//第五个参数,发送数据的目标地址
	//第六个参数, 目标地址的长度,一般为sizeof(SOCKADDR)
(2)接收数据函数recvfrom

int recvfrom(
	SOCKET s,
	char FAR* buf,              
	int len,
	int flags,                  
	struct sockaddr FAR *from,
	int FAR *fromlen 
	);
	//第一个参数,需要接收的数据的套接字
	//第二个参数,存储接收的数据的数组
	//第三个参数,接收数据的长度
	//第四个参数, 标志位,一般为0
	//第五个参数,接收数据的源地址
	//第六个参数, 源地址的长度,一般为sizeof(SOCKADDR)
5.其他常用函数

(1)htonl() 将主机的无符号长整形数转换成网络字节顺序。

  #include <winsock.h>
  u_long PASCAL FAR htonl( u_long hostlong);
   hostlong:主机字节顺序表达的32位数。
  注释:本函数将一个32位数从主机字节顺序转换成网络字节顺序。
  返回值:htonl()返回一个网络字节顺序的值。
(2)htons() 将主机的无符号短整形数转换成网络字节顺序。

  #include <winsock.h>
  u_short PASCAL FAR htons( u_short hostshort);
  hostshort:主机字节顺序表达的16位数。
  注释:本函数将一个16位数从主机字节顺序转换成网络字节顺序。
  返回值:htons()返回一个网络字节顺序的值。
(3)inet_addr():将一个点间隔地址转换成一个in_addr。

  #include <winsock.h>
  unsigned long PASCAL FAR inet_addr( const struct FAR* cp);
  cp:一个以Internet标准“.”间隔的字符串。
  注释:本函数解释cp参数中的字符串,这个字符串用Internet的“.”间隔格式表示一个数字的Internet地址。返回值可用作Internet地址。所有Internet地址以网络字节顺序返回(字节从左到右排列)。

返回值:若无错误发生,inet_addr()返回一个无符号长整型数,其中以适当字节顺序存放Internet地址。如果传入的字符串不是一个合法的Internet地址,如“a.b.c.d”地址中任一项超过255,那么inet_addr()返回INADDR_NONE。

(4)inet_ntoa()将网络地址转换成“.”点隔的字符串格式。

  #include <winsock.h>
  char FAR* PASCAL FAR inet_ntoa( struct in_addr in);
  in:一个表示Internet主机地址的结构。
  注释: 本函数将一个用in参数所表示的Internet地址结构转换成以“.” 间隔的诸如“a.b.c.d”的字符串形式。请注意inet_ntoa()返回的字符串存放在WINDOWS套接口实现所分配的内存中。应用程序不应假设该内存是如何分配的。在同一个线程的下一个WINDOWS套接口调用前,数据将保证是有效。

返回值:若无错误发生,inet_ntoa()返回一个字符指针。否则的话,返回NULL。其中的数据应在下一个WINDOWS套接口调用前复制出来。







  • 3
    点赞
  • 13
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值