Windos Socket的实现
Windows socket 是microsoft windows的网络程序设计接口,它是从berkeley socket扩展而来,以动态链接库的形式提供给我们使用。windows socket在继承了berkeley socket主要特征的基础上,又对它进行了重要扩充。这些扩充主要是提供了一些异步函数,并增加了符合windows消息驱动特性的网络事件异步选择机制。
套接字类型
流式套接字(SOCK_STREAM)
提供面向连接、可靠地数据传输服务,数据无差错,无重复的发送,并且按照发送顺序接收。流式套接字实际上是基于TCP协议实现的
数据报式套接字(SOCK_DGRAM)
提供无连接服务。数据包以独立包形式发送,不提供无错保证,数据可能丢失或者重复,并且接收顺序混乱。数据包式套接字实际上是基于UDP协议实现的
代码例子
服务端
// WinSocketSrv.cpp : 定义控制台应用程序的入口点。
//
#include "stdafx.h"
#include <winsock2.h>
#include <cstdio>
#include <process.h>
#pragma comment (lib,"ws2_32.lib")
unsigned int _stdcall RecvProc(void*lpParameter)
{
SOCKET*psock=(SOCKET*)lpParameter;
char buf[1024]={0};
if(recv(*psock,buf,1024,0)==SOCKET_ERROR)
{
printf("recv() failed,error code:%d\n",WSAGetLastError());
closesocket(*psock);
_endthreadex(0);
return 0;
}
printf("收到:%s\n",buf);
closesocket(*psock);
_endthreadex(0);
return 1;
}
bool InitSocket()
{
WSADATA wsaData;
WORD wVersion;
ZeroMemory(&wsaData,sizeof(WSADATA));
wVersion=MAKEWORD(2,2);
if(WSAStartup(wVersion,&wsaData)!=0)
{
printf("WSAStartup() failed,error code:%d\n",WSAGetLastError());
return false;
}
if(LOBYTE(wsaData.wVersion)!=2||HIBYTE(wsaData.wVersion)!=2)
{
printf("LOBYTE()、HIBYTE() failed!\n");
WSACleanup();
return false;
}
return true;
}
bool StartSrv(char*szIP,unsigned short usPort,bool bStyle)
{
//bStyle--true TCP;false UDP;
SOCKET sock;
if(bStyle)
{
sock =socket(AF_INET,SOCK_STREAM,0);
if(sock==INVALID_SOCKET)
{
printf("socket() failed,error code:%d\n",WSAGetLastError());
WSACleanup();
return false;
}
SOCKADDR_IN addrSrv;
ZeroMemory(&addrSrv,sizeof(SOCKADDR_IN));
addrSrv.sin_family =AF_INET;
addrSrv.sin_addr.S_un.S_addr=inet_addr(szIP);
addrSrv.sin_port =htons(usPort);
int flag=1;
int len =sizeof(int);
if(setsockopt(sock,SOL_SOCKET,SO_REUSEADDR,(const char*)&flag,len)==SOCKET_ERROR)
{
printf("setsockopt() failed,error code:%d\n",WSAGetLastError());
closesocket(sock);
WSACleanup();
return false;
}
if(bind(sock,(SOCKADDR*)&addrSrv,sizeof(SOCKADDR_IN))==SOCKET_ERROR)
{
printf("bind() failed,error code:%d\n",WSAGetLastError());
closesocket(sock);
WSACleanup();
return false;
}
if(listen(sock,100)==SOCKET_ERROR)
{
printf("listen() failed,error code:%d\n",WSAGetLastError());
closesocket(sock);
WSACleanup();
return false;
}
while(1)
{
SOCKET rs;
SOCKADDR_IN client;
int len =sizeof(SOCKADDR_IN);
ZeroMemory(&client,sizeof(SOCKADDR_IN));
rs=accept(sock,(SOCKADDR*)&client,&len);
if(rs==INVALID_SOCKET)
{
printf("accept() failed,error code:%d\n",WSAGetLastError());
closesocket(sock);
WSACleanup();
return false;
}
HANDLE hTcp =(HANDLE)_beginthreadex(NULL,0,RecvProc,(void*)&rs,0,NULL);
WaitForSingleObject(hTcp,INFINITE);
CloseHandle(hTcp);
}
}
else
{
sock =socket(AF_INET,SOCK_DGRAM,0);
if(sock==INVALID_SOCKET)
{
printf("socket() failed,error code:%d\n",WSAGetLastError());
WSACleanup();
return false;
}
SOCKADDR_IN addrSrv;
ZeroMemory(&addrSrv,sizeof(SOCKADDR_IN));
addrSrv.sin_family=AF_INET;
addrSrv.sin_addr.S_un.S_addr=inet_addr(szIP);
addrSrv.sin_port=htons(usPort);
int flag=1;
int len =sizeof(int);
if(setsockopt(sock,SOL_SOCKET,SO_REUSEADDR,(const char*)&flag,len)==SOCKET_ERROR)
{
printf("setsockopt() failed,error code:%d\n",WSAGetLastError());
closesocket(sock);
WSACleanup();
return false;
}
if(bind(sock,(SOCKADDR*)&addrSrv,sizeof(SOCKADDR_IN))==SOCKET_ERROR)
{
printf("bind() failed,error code:%d\n",WSAGetLastError());
closesocket(sock);
WSACleanup();
return false;
}
while(1)
{
char buf[1024]={0};
SOCKADDR_IN client;
int len =sizeof(SOCKADDR_IN);
ZeroMemory(&client,sizeof(SOCKADDR_IN));
if(recvfrom(sock,buf,1024,0,(SOCKADDR*)&client,&len)==SOCKET_ERROR)
{
printf("recvfrom() failed,error code:%d\n",WSAGetLastError());
closesocket(sock);
WSACleanup();
return false;
}
printf("收到:%s\n",buf);
}
}
return true;
}
int _tmain(int argc, _TCHAR* argv[])
{
if(InitSocket())
{
StartSrv("127.0.0.1",8080,false);
}
printf("exit!\n");
return 0;
}
客户端
//
#include "stdafx.h"
#include <winsock2.h>
#include <cstdio>
#include <process.h>
#pragma comment (lib,"ws2_32.lib")
unsigned int _stdcall RecvProc(void*lpParameter)
{
SOCKET*psock=(SOCKET*)lpParameter;
char buf[1024]={0};
if(recv(*psock,buf,1024,0)==SOCKET_ERROR)
{
printf("recv() failed,error code:%d\n",WSAGetLastError());
closesocket(*psock);
_endthreadex(0);
return 0;
}
printf("收到:%s\n",buf);
closesocket(*psock);
_endthreadex(0);
return 1;
}
bool InitSocket()
{
WSADATA wsaData;
WORD wVersion;
ZeroMemory(&wsaData,sizeof(WSADATA));
wVersion=MAKEWORD(2,2);
if(WSAStartup(wVersion,&wsaData)!=0)
{
printf("WSAStartup() failed,error code:%d\n",WSAGetLastError());
return false;
}
if(LOBYTE(wsaData.wVersion)!=2||HIBYTE(wsaData.wVersion)!=2)
{
printf("LOBYTE()、HIBYTE() failed!\n");
WSACleanup();
return false;
}
return true;
}
bool StartSrv(char*szIP,unsigned short usPort,bool bStyle)
{
//bStyle--true TCP;false UDP;
SOCKET sock;
if(bStyle)
{
sock =socket(AF_INET,SOCK_STREAM,0);
if(sock==INVALID_SOCKET)
{
printf("socket() failed,error code:%d\n",WSAGetLastError());
WSACleanup();
return false;
}
SOCKADDR_IN addrSrv;
ZeroMemory(&addrSrv,sizeof(SOCKADDR_IN));
addrSrv.sin_family =AF_INET;
addrSrv.sin_addr.S_un.S_addr=inet_addr(szIP);
addrSrv.sin_port =htons(usPort);
int flag=1;
int len =sizeof(int);
if(setsockopt(sock,SOL_SOCKET,SO_REUSEADDR,(const char*)&flag,len)==SOCKET_ERROR)
{
printf("setsockopt() failed,error code:%d\n",WSAGetLastError());
closesocket(sock);
WSACleanup();
return false;
}
if(bind(sock,(SOCKADDR*)&addrSrv,sizeof(SOCKADDR_IN))==SOCKET_ERROR)
{
printf("bind() failed,error code:%d\n",WSAGetLastError());
closesocket(sock);
WSACleanup();
return false;
}
if(listen(sock,100)==SOCKET_ERROR)
{
printf("listen() failed,error code:%d\n",WSAGetLastError());
closesocket(sock);
WSACleanup();
return false;
}
while(1)
{
SOCKET rs;
SOCKADDR_IN client;
int len =sizeof(SOCKADDR_IN);
ZeroMemory(&client,sizeof(SOCKADDR_IN));
rs=accept(sock,(SOCKADDR*)&client,&len);
if(rs==INVALID_SOCKET)
{
printf("accept() failed,error code:%d\n",WSAGetLastError());
closesocket(sock);
WSACleanup();
return false;
}
HANDLE hTcp =(HANDLE)_beginthreadex(NULL,0,RecvProc,(void*)&rs,0,NULL);
WaitForSingleObject(hTcp,INFINITE);
CloseHandle(hTcp);
}
}
else
{
sock =socket(AF_INET,SOCK_DGRAM,0);
if(sock==INVALID_SOCKET)
{
printf("socket() failed,error code:%d\n",WSAGetLastError());
WSACleanup();
return false;
}
SOCKADDR_IN addrSrv;
ZeroMemory(&addrSrv,sizeof(SOCKADDR_IN));
addrSrv.sin_family=AF_INET;
addrSrv.sin_addr.S_un.S_addr=inet_addr(szIP);
addrSrv.sin_port=htons(usPort);
int flag=1;
int len =sizeof(int);
if(setsockopt(sock,SOL_SOCKET,SO_REUSEADDR,(const char*)&flag,len)==SOCKET_ERROR)
{
printf("setsockopt() failed,error code:%d\n",WSAGetLastError());
closesocket(sock);
WSACleanup();
return false;
}
if(bind(sock,(SOCKADDR*)&addrSrv,sizeof(SOCKADDR_IN))==SOCKET_ERROR)
{
printf("bind() failed,error code:%d\n",WSAGetLastError());
closesocket(sock);
WSACleanup();
return false;
}
while(1)
{
char buf[1024]={0};
SOCKADDR_IN client;
int len =sizeof(SOCKADDR_IN);
ZeroMemory(&client,sizeof(SOCKADDR_IN));
if(recvfrom(sock,buf,1024,0,(SOCKADDR*)&client,&len)==SOCKET_ERROR)
{
printf("recvfrom() failed,error code:%d\n",WSAGetLastError());
closesocket(sock);
WSACleanup();
return false;
}
printf("收到:%s\n",buf);
}
}
return true;
}
int _tmain(int argc, _TCHAR* argv[])
{
if(InitSocket())
{
StartSrv("127.0.0.1",8080,false);
}
printf("exit!\n");
return 0;
}
客户端
// WinSocketClt.cpp : 定义控制台应用程序的入口点。
//
#include "stdafx.h"
#include <winsock2.h>
#include <cstdio>
#pragma comment (lib,"ws2_32.lib")
bool InitSocket()
{
WSADATA wsaData;
WORD wVersion;
ZeroMemory(&wsaData,sizeof(WSADATA));
wVersion=MAKEWORD(2,2);
if(WSAStartup(wVersion,&wsaData)!=0)
{
printf("WSAStartup() failed,error code:%d\n",WSAGetLastError());
return false;
}
if(LOBYTE(wsaData.wVersion)!=2||HIBYTE(wsaData.wVersion)!=2)
{
printf("LOBYTE()、HIBYTE() failed!\n");
WSACleanup();
return false;
}
return true;
}
bool StartSrv(char*szIP,unsigned short usPort,bool bStyle,char*szBuf,int iLen)
{
//bStyle--true TCP;false UDP;
SOCKET sock;
if(bStyle)
{
sock =socket(AF_INET,SOCK_STREAM,0);
if(sock==INVALID_SOCKET)
{
printf("socket() failed,error code:%d\n",WSAGetLastError());
WSACleanup();
return false;
}
SOCKADDR_IN addrSrv;
ZeroMemory(&addrSrv,sizeof(SOCKADDR_IN));
addrSrv.sin_family =AF_INET;
addrSrv.sin_addr.S_un.S_addr=inet_addr(szIP);
addrSrv.sin_port =htons(usPort);
if(connect(sock,(SOCKADDR*)&addrSrv,sizeof(SOCKADDR))==SOCKET_ERROR)
{
printf("connect() failed,error code:%d\n",WSAGetLastError());
closesocket(sock);
WSACleanup();
return false;
}
if(send(sock,szBuf,iLen,0)==SOCKET_ERROR)
{
printf("send() failed,error code:%d\n",WSAGetLastError());
closesocket(sock);
WSACleanup();
return false;
}
}
else
{
sock =socket(AF_INET,SOCK_DGRAM,0);
if(sock==INVALID_SOCKET)
{
printf("socket() failed,error code:%d\n",WSAGetLastError());
WSACleanup();
return false;
}
SOCKADDR_IN addrSrv;
ZeroMemory(&addrSrv,sizeof(SOCKADDR_IN));
addrSrv.sin_family=AF_INET;
addrSrv.sin_addr.S_un.S_addr=inet_addr(szIP);
addrSrv.sin_port=htons(usPort);
if(sendto(sock,szBuf,iLen,0,(SOCKADDR*)&addrSrv,sizeof(SOCKADDR))==SOCKET_ERROR)
{
printf("sendto() failed,error code:%d\n",WSAGetLastError());
closesocket(sock);
WSACleanup();
return false;
}
}
return true;
}
int _tmain(int argc, _TCHAR* argv[])
{
if(InitSocket())
{
while(1)
{
char buf[]="www.baidu.com";
StartSrv("127.0.0.1",8080,false,buf,strlen(buf)+1);
}
}
printf("exit!\n");
return 0;
}
//
#include "stdafx.h"
#include <winsock2.h>
#include <cstdio>
#pragma comment (lib,"ws2_32.lib")
bool InitSocket()
{
WSADATA wsaData;
WORD wVersion;
ZeroMemory(&wsaData,sizeof(WSADATA));
wVersion=MAKEWORD(2,2);
if(WSAStartup(wVersion,&wsaData)!=0)
{
printf("WSAStartup() failed,error code:%d\n",WSAGetLastError());
return false;
}
if(LOBYTE(wsaData.wVersion)!=2||HIBYTE(wsaData.wVersion)!=2)
{
printf("LOBYTE()、HIBYTE() failed!\n");
WSACleanup();
return false;
}
return true;
}
bool StartSrv(char*szIP,unsigned short usPort,bool bStyle,char*szBuf,int iLen)
{
//bStyle--true TCP;false UDP;
SOCKET sock;
if(bStyle)
{
sock =socket(AF_INET,SOCK_STREAM,0);
if(sock==INVALID_SOCKET)
{
printf("socket() failed,error code:%d\n",WSAGetLastError());
WSACleanup();
return false;
}
SOCKADDR_IN addrSrv;
ZeroMemory(&addrSrv,sizeof(SOCKADDR_IN));
addrSrv.sin_family =AF_INET;
addrSrv.sin_addr.S_un.S_addr=inet_addr(szIP);
addrSrv.sin_port =htons(usPort);
if(connect(sock,(SOCKADDR*)&addrSrv,sizeof(SOCKADDR))==SOCKET_ERROR)
{
printf("connect() failed,error code:%d\n",WSAGetLastError());
closesocket(sock);
WSACleanup();
return false;
}
if(send(sock,szBuf,iLen,0)==SOCKET_ERROR)
{
printf("send() failed,error code:%d\n",WSAGetLastError());
closesocket(sock);
WSACleanup();
return false;
}
}
else
{
sock =socket(AF_INET,SOCK_DGRAM,0);
if(sock==INVALID_SOCKET)
{
printf("socket() failed,error code:%d\n",WSAGetLastError());
WSACleanup();
return false;
}
SOCKADDR_IN addrSrv;
ZeroMemory(&addrSrv,sizeof(SOCKADDR_IN));
addrSrv.sin_family=AF_INET;
addrSrv.sin_addr.S_un.S_addr=inet_addr(szIP);
addrSrv.sin_port=htons(usPort);
if(sendto(sock,szBuf,iLen,0,(SOCKADDR*)&addrSrv,sizeof(SOCKADDR))==SOCKET_ERROR)
{
printf("sendto() failed,error code:%d\n",WSAGetLastError());
closesocket(sock);
WSACleanup();
return false;
}
}
return true;
}
int _tmain(int argc, _TCHAR* argv[])
{
if(InitSocket())
{
while(1)
{
char buf[]="www.baidu.com";
StartSrv("127.0.0.1",8080,false,buf,strlen(buf)+1);
}
}
printf("exit!\n");
return 0;
}