WinSock网络通信

前言:

Winsock是Windows下的网络编程接口,它是由Unix下的BSD Socket发展而来,是一个与网络协议无关的编程接口。
构建编程环境
Winsock在常见的Windows平台上有两个主要的版本,即Winsock1和Winsock2。编写与Winsock1兼容的程序你需要引用头文件WINSOCK.H,如果编写使用Winsock2的程序,则需要引用WINSOCK2.H。此外还有一个MSWSOCK.H头文件,它是专门用来支持在Windows平台上高性能网络程序扩展功能的。使用WINSOCK.H头文件时,同时需要库文件WSOCK32.LIB,使用WINSOCK2.H时,则需要WS2_32.LIB,如果使用MSWSOCK.H中的扩展API,则需要MSWSOCK.LIB。正确引用了头文件,并链接了对应的库文件,你就构建起编写WINSOCK网络程序的环境了。
初始化Winsock
每个Winsock程序必须使用WSAStartup载入合适的Winsock动态链接库,如果载入失败,WSAStartup将返回SOCKET_ERROR


主要代码分析

服务端程序:
第一步:包含WinSocket的头文件和动态链接库(DLL)

#include <Winsock2.h>
#include <windows.h>
#pragma comment(lib,"ws2_32")

第二步:初始化WSAStartup

WSAStarup的原型如下:
int WSAStartup(
  __in   WORD wVersionRequested,
  __out  LPWSADATA lpWSAData
);

其中的第一个参数是版本,第二个参数是一个指向WSADATA结构体的指针,代码如下:

WORD Version = MAKEWORD(2,2);  //通过MAKEWORD来设定版本,高版本和低版本都为2,也就是限定了版本必须为2
WSADATA wsadata ;    //结构体的一个成员 wsadata
//初始化并判断是不是成功,如果成功的话返回的是0,不成功的话返回的值为非0,那么就要使用WSAleanup()函数了
if(WSAStartup(Version,&wsadata)){
cout<<" WSAStartup出错!"<<endl;
WSACleanup();
}

第三步,初始化一个Socket
在MSDN中socket的原型如下

SOCKET WSAAPI socket(
  __in  int af,
  __in  int type,
  __in  int protocol
);

其中第一个参数为网络层协议类型,第二个参数为socket类型,第三个参数为传输层的协议类型,代码如下:

//第一个参数多数时候为AF_INET,第二个参数可以为SOCK_STREAM适用于可信连接,也就是tcp链接,或者为SOCK_DGRAM,适用于UDP协议
第三个参数为传输层协议,如果第二个参数为SOCK_STREAM,这里就为IPPROTO_TCP,如果是SOCK_DGRAM,这里就为IPPROTO_UDP

SOCKET ServerSocket=socket(AF_INET,SOCK_STREAM,IPPROTO_TCP);
if(ServerSocket ==INVALID_SOCKET){
    cout<<"套接字打开错误"<<endl;
}

第四步:bind

在MSDN中bind的定义如下:
int bind(
  __in  SOCKET s,
  __in  const struct sockaddr* name,
  __in  int namelen
);

第一个参数一个已经初始化的socket,第一个参数为执行sockaddr或者是sockaddr_in的结构体的起始地址,
第三个参数为结构体的大小,代码如下:

sockaddr_in  ServerAddr;//定义一个结构体成员,这里使用的是sockaddr_in结构体
ServerAddr.sin_family=AF_INET;//初始化成员的sin_family为AF_INET
ServerAddr.sin_addr.S_un.S_addr=INADDR_ANY;//允许任意的IP地址进行连接
int duankou;
cout << "请输入端口号:" ;
cin >> duankou;
ServerAddr.sin_port=htons(duankou);//侦听端口为duankou,这里使用了htons函数
//这里需要说明的是需要对第二个参数进行强制类型转换,(LPSOCKADDR)&ServerAddr,并且判断是不是bind成功,成功后返回的是为0
if(bind(ServerSocket,(LPSOCKADDR)&ServerAddr,sizeof(ServerAddr))){
    cout<<"接口捆绑失败(bind Fail)"<<endl;
}

第五步:侦听

在MSDN中listen的原型如下:
int listen(
  __in  SOCKET s,
  __in  int backlog
);

依然第一个参数为初始化了的socket,第二个参数为最大允许的连接数,代码如下:

//这里依然使用的是上面的socket:ServerSocket
if(listen(ServerSocket,5)){
    cout<<"监听失败(listen Fail)"<<endl;
}

第六步:accept

在MSDN中原型如下:
SOCKET accept(
  __in     SOCKET s,
  __out    struct sockaddr* addr,
  __inout  int* addrlen
);

第一个参数一个新的客户端的Socket,这里需要定义一个,第二个参数依然为执行sockaddr或者是sockaddr_in的结构体的首地址,第三个参数为长度,这里accept负责对新定义的socket进行初始化,如果成功accept返回的一个可用的sokcet。
代码如下:

sockaddr_in Clientaddr;//定义一个结构体成员
SO
  • 0
    点赞
  • 3
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

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

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

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值