基于Win32平台下Winsock API的网络编程

 
引言
Intemet发展到今天可谓如火如荼,而作为Intemet的基础——Socket接口——又是很多协议(如:HTTP、FTP、POP3、SMTP、IRC)的基础。在网络编程中应用最广泛的是Winsoek API。Windows程序的网络通信一般都是调用Winsock API实现的。使用Winsock API的编程,应该了解一些TCP/IP的基础知识。虽然可以直接使用Winsock API来写网络应用程序,但是,对TCP/IP协议有了深入的了解,有助于写出优秀的网络应用程序。
 
1 TCP/IP协议与Winsock网络编程 接口的关系
首先,介绍一下Winsoek与TCP/IP的关系。Winsoek并不是一种网络协议,它只是一个网络编程接口,也就是说,它不是协议,但是它可以访问很多种网络协议,可以把它当作一些协议的封装。现在的Winsoek已经基本上实现了与协议无关。也就是说,可以使用Winsock来调用多种协议的功
能。
那么,Winsock和TCP/IP协议到底是什么关系呢?实际上,Winsoek就是TCP/IP协议的一种封
装,可以通过调用Winsock的接口函数来调用TCP/IP)的各种功能。例如,想用TCP/IP协议发送数据,你就可以使用Winsock的接口函数send()来调用T℃P/IP的发送数据功能,至于具体怎么发送数据,Winsock已经帮你封装好了这种功能。
 
2 TCP/IP协议介绍
现在来介绍一些TCP/IP的原理。TCP/IP协议包含的范围非常的广,它是一种四层协议,包含了各种硬件软件的定义,这里只介绍软件方面的知识。TCP/IP协议确切的说法应该是TCP/UDP/IP协 议。
UDP协议(User Dadagram Protocol用户数据报协议)。是一种保护消息边界的,不保障可靠数据
的传输的面向非连接的协议。TCP协议(Tansmission Control Protocol传输控制协议)。是一种流传输的协议。它提供可靠的,有序的,双向的,面向连接的传输。
保护消息边界,就是指传输协议把数据当作一条独立的消息在网上传输,接收端只能接收独立的消息,也就是说存在消息边界,接收端一次只能接收发送端发出的一个数据包。而面向流则是指无保护消息保护边界的,如果发送端连续发送数据, 接收端有可能在一次接收动作中,会收到两个或者 更多的数据包。所以在使用TCP协议通讯时,在连续发送数据时,若使用的缓冲区足够大,不能只解析检查第一个数据包,而忽略已经接收的其他数据包。在作这类的网络编程时,必须要注意这一 点。
 
3 Winsock编程简单的流程
下面介绍一下Win32平台的Winsock编程方 法。
作为通讯必须有服务器端和客户端。简单介绍TCP服务器端的大体流程。
对于任何基于Winsock的编程首先必须要初 始化Winsock DLL库。
int WSAStarup(WORD wVersionRequested,LP WSDATA ipWsAData);
wVersionRequested是要求使用的Winsock的版本。调用这个接口函数可以初始化Winsock。然后
必须创建一个套接字(socket)。
SOCKET socket(int af,int type,int protoco1);
套接字可以说是Winsock通讯的核心。Winsock通讯的所有数据传输,都是通过套接字来完成的,套接字包含了两个信息,一个是IP地址,一个是Port端口号,使用这两个信息,就可以确定网络
中的任何一个通讯节点。
当调用了socket()接口函数创建了一个套接 字后,必须把套接字与你需要进行通讯的地址建立 联系,可以通过绑定函数来实现这种联系。
 
Int bind(SOCKET S,const struct sockaddr FAR *name,int namelen);
Struct sockaddr_ in
{
short sin_family;
U short sin_prot;
struct in_ addr sin_addr;
char sin_ sero[8];
}
 
通过绑定操作就包含了所需要建立连接的本地的地址,包括:地址族,IP和端口信息。Sin_fami1y字段必须把它设为AF_INET,这是告诉Winsock使用的是IP地址族。Sin_prot就是要用来通讯的端口号。sin addr就是要用来通讯的IP地址信息。
在这里,必须提到有关“大头(big—endian)”“小头(1ittle—endian)”。因为各种不同的计算机处理数据时的方法是不一样的,Intel 86处理器上是 用“小头”来表示多字节的编号,就是把低字节放在 前面,把高字节放在后面,而互联网标准却正好相 反,所以,必须把主机字节转换成网络字节的顺序。
 
Winsock API提供了几个函数。
把主机字节转化成网络字节的函数:
u_long htonl(u_long hostlong);
u_ short htons(u_short hostshort);
 
把网络字节转化成主机字节的函数:
u_long htonl(u_long netlong);
u_sh ort htons(u_short neshort);
 
这样,在设置IP地址和port端口时,就必须把 主机字节转化成网络字节后,才能用bind()函数来绑定套接字和地址。 当绑定完成之后,服务器必须建立一个监听的队列来接收客户端的连接请求。
int listen(SOCKET S,int backlog);
这个函数可以把套接字转成监听模式。如果客户端有了连接请求,还必须使用
int accept(SOCKET S,struct sockaddr FAR addr,int FAR addrlen);
来接受客户端的请求。
 
现在已经完成了一个服务器的建立,而客户端的建立的流程则是初始化WinSock,然后创建sock et套接字,再使用
int connect(SOCKET S,const struct sockaddr FAR *name,int namelen);
来连接服务端。
 
下面是一个最简单的创建服务器端和客户端 的例子:
 
服务器端的创建:
WSADATA wsd;
SOCKET sListen;
SOCKET sclient;
UINT port=800;
int iAddrSize;
struct sockadd_in local,client;
 
WSAStartup(0xl1,&wsa);
sListen = socket (AF INET, SOCK_STRE AMIPPOTO _ IP);
laca1.Sin_family = AF INET;
loca1.sin_addr = htonl(INADDR_ANY);
loca1.sin_port = htons(port);
bind(sListen,(struct sockaddr )&local,size of(1oca1));
listen(sListen,5);
sClient= accept(sListen,(struct sockaddr*)&client,&iAddrsize);
 
客户端的创建:
WSADATA wsd;
SOCKET sClient;
UNIT port=800:
Char szIp[]=”127.0.0.1”;
int iAddrSize;
struct sockaddr in sever;
 
WSAStartup (0xll,&wsd);
sClient=socket(AF_INET,SOCK_STREAM,IPPOTO_ip);
server.sin_family = AF _ INET;
server .sin_ addr=inet_addr(szIp);
server. sin_port=htons(port);
conect(sClient,(struct sockaddr*)&server,sizeof(sever));
 
当服务器端和客户端建立连接后,无论是客户端,还是服务器端都可以使用。
int send(SoCKET s,const char FAR buf,int len,int fLa );
int recv(SOCKRT S,char FAR buf,int len,int fLa );
函数来接收和发送数据,因为TCP连接是双向的。当要关闭通讯连接的时候,任何一方都可以调用。
int shutdown(SOCKET S,int how);
来关闭套接字的指定功能。再调用。
int closesocket(SoCKET S);
来关闭套接字句柄。这样一个通讯过程就算 完成了。需要说明的是在上面的代码中没有任何检查函数指定返回值,在实际的网络编程中一定要检查任何一个Winsock API函数的调用结果,因为很多 时候函数调用并不一定成功。上面介绍的函数,返 回值类型是int时,如果函数调用失败的话,返回的值都是SOCKET_ERROR。
 
 
  • 0
    点赞
  • 1
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

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

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

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值