Windows socket 编程汇总

 

一常用数据结构

1 SOCKET

typedef u_int           SOCKET

其实就是一个无符号的整数,是一个socket描述符,我的理解就是 ,指向系统内核的”指针”,但这个”指针”要靠系统维护,我们只能获取,还要负责释放.

 

2 SOCKADDR_IN

struct sockaddr_in{ short sin_family; unsigned short sin_port; IN_ADDR sin_addr;

 char sin_zero[8];};

用来指定本地或远程的地址,以此来进行socket连接

sin_family:指定为AF_INET

sin_port: 指定所连接的端口号,用htons将short的端口号进行转换,如htons(6000)

sin_addr:指定所连接的ip,用inet_addr装换,如inet_addr(“127.0.0.1”)

sin_zero:为了和SOCKADDR的大小相同,而进行的填充,应该将其初始化为0

 

 

二 常用函数

1 WSAStartup

原型:

 int WSAStartup(WORD wVersionRequested,LPWSADATA lpWSAData)

作用:

用来初始化ws2_32.lib

返回值

成功返回0

 

2 WSACleanup

终止ws2_32.lib

 

3 socket

原型:

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

参数说明

af:指定地址家族,AF_INET

type: SOCK_STREAMSOCK_DGRAM,前者用于TCP,后者用于UDP

protocol:设置为0即可

作用:

创建一个SOCKET

返回值

创建失败返回INVALID_SOCKET

 

4 bind

原型:

int bind( SOCKET s, const struct sockaddr FAR *name,int namelen );

参数说明

s:server端已经创建好的SOCKET

name:server的SOCKADDR_IN结构,需要做强制类型转换,注意,他和SOCKADDR的大小一样

namelen:顾名思义,name的size大小,注意他和SOCKADDR的大小一样

作用

SOCKET绑定到机器上

返回值

成功返回0,错误返回SOCKET_ERROR

 

5 listen

原型

int listen(  SOCKET s,      int backlog  );

参数说明

s: 服务端未连接的SOCKET

backlog:最大可连接数

作用

设置tcp服务端

返回值

成功返回0,失败返回SOCKET_ERROR

 

6 accept

原型

SOCKET accept(  SOCKET s,  struct sockaddr FAR *addr,  int FAR *addrlen);

参数说明

s:tcp服务端的SOCKET

addr:远程客户端的地址信息

addlen:addrsize

作用

从已经获得许可的连接中关联一个新的SOCKET

返回值

成功返回新的SOCKET的值,错误返回INVALID_SOCKET

 

7 send

原型

int send(SOCKET s, const char FAR *buf,  int len, int flags );

参数说明

s:对方的SOCKET

buf:要发送的缓冲区的地址

flags:通常置为0

作用

向对方发送数据

返回值

成功返回已发送的数据的字节数,错误返回SOCKET_ERROR

 

8 recv

原型

int recv(  SOCKET s, char FAR *buf, int len, int flags       );

参数说明

s:对方的SOCKET

buf:要发送的缓冲区的地址

flags:通常置为0

作用

接受对方的数据

返回值

成功返回已接受的数据的字节数,错误返回SOCKET_ERROR

 

9 closesocket

原型

int closesocket(  SOCKET s  );

参数说明

s:要关闭的SOCKET

作用

关闭指定的SOCKET

返回值

成功返回0,错误返回SOCKET_ERROR

 

10 connect

原型

Int connect(SOCKET s,const struct sockaddr FAR *name,int namelen)                        );

参数说明

S:本地SOCKET

name:远程服务端地址信息

namelen:namesize

作用

远程socket连接

返回值

成功返回0,错误返回SOCKET_ERROR

 

11 sendto

原型

int sendto(  SOCKET s, const char FAR *buf,  int len, int flags, const struct sockaddr FAR *to,    int tolen);                        );

参数说明

S:对方的SOCKET,可能是连接状态

buf:要发送的信息地址

len:信息的大小

flags:通常置为0

to:远程地址信息

tolen:tosize

作用

用于UDP,数据的发送

返回值

成功返回已发送的数据的字节数,错误返回SOCKET_ERROR

 

12 recvfrom

原型

int recvfrom(  SOCKET s, char FAR* buf, int len, int flags, struct sockaddr FAR *from, int FAR *fromlen );

参数说明

S:对方的SOCKET,可能是连接状态

buf:用于接收的缓冲区地址

len:信息的大小

flags:通常置为0

from:接收远程地址信息

fromlen:tosize

作用

用于UDP,数据的接收

返回值

成功返回已接收的数据的字节数,错误返回SOCKET_ERROR

 

15 WSAGetLastError

原型: int  WSAGetLastError (void);

作用:返回最后一次的错误代码

错误代码在WINSOCK2.H中定义

 

14 一些转换函数

ntohs:”network to host short”

ntohl:”network to host long”

htons:”host to network short”

htonl:”host to network long”

inet_addr:将字符串的IP转换为网络IP

 

三正式编程

以下程序在vc6.0 下编译

1 tcp编程

TCP  Server:

/************************************************************************/
/*
准备步骤
#include <WINSOCK2.H>
#pragma     comment(lib, "ws2_32.lib ")

服务器端编程的步骤:
0:加载套接字库(WSAStartup())

1:创建套接字(socket());
  
2:绑定套接字到一个IP地址和一个端口上(bind());
	
3:将套接字设置为监听模式等待连接请求(listen());
	  
4:请求到来后,接受连接请求,返回一个新的对应于此次连接的套接字(accept());
		
5:用返回的套接字和客户端进行通信(send()/recv());
		  
6:返回,等待另一连接请求;
			
7:关闭套接字(closesocket())

8:关闭加载的套接字库(WSACleanup())。

                                                                        */
/************************************************************************/
#include <WINSOCK2.H>
#include <windows.h>
#include <iostream>
#include <string>
using namespace std;
#pragma     comment(lib, "ws2_32.lib ")


//0 
bool LoadWSA();
//1
bool CreateSocket(SOCKET& sock,int type=SOCK_STREAM);
//2
bool BindSocket(SOCKET& sock,short port ,const char* strIp);
//3
bool SetListen(SOCKET& sock,int number);
//4,5,6
bool Communicate(SOCKET& srverSock);
//7
bool CloseSocket(SOCKET& sock);
//8
void CloseWSA();

void ExitWithErrorMessage(const string& errMsg);

DWORD WINAPI ClientThread(LPVOID sockCliet);
 
void main()
{
	cout<<"start server.\n";

	if(!LoadWSA() )
		ExitWithErrorMessage("LoadWSA  failed.");
	cout<<"LoadWAS success.\n";

	SOCKET serSock;

	if(!CreateSocket(serSock) )
		ExitWithErrorMessage("create server socket failed.");
	cout<<"CreateSocket success.\n";

	if(!BindSocket(serSock,6000,"127.0.0.1") )
		ExitWithErrorMessage("BindSocket failed.");
	cout<<"BindSocket success.\n";

	if(!SetListen(serSock,10) )
		ExitWithErrorMessage("SetListen failed.");
	cout<<"SetListen success.\n";
	
	if(!Communicate(serSock) )
		ExitWithErrorMessage("Communicate failed.");
	cout<<"Communicate success.\n";

	if(! CloseSocket(serSock) )
		ExitWithErrorMessage("CloseSocket failed.");
	cout<<"CloseSocket success.\n";

	CloseWSA();
	cout<<"CloseWSA success.\n";
}


bool LoadWSA()
{
	WSAData wsaData;

	if( 0 == WSAStartup(MAKEWORD(2,2),&wsaData) )
	{
		return true;
	}

	return false;
}

void CloseWSA()
{
	WSACleanup();
}

bool CreateSocket(SOCKET& sock,int type/* =SOCK_STREAM */)
{
	sock=socket(AF_INET,type,0);

	if(INVALID_SOCKET == sock)
	{
		return false;
	}

	return true;
}

bool BindSocket(SOCKET& sock,short port ,const char* strIp)
{
	SOCKADDR_IN address;
	
	address.sin_family=AF_INET;		
	address.sin_addr.s_addr =inet_addr(strIp);
	address.sin_port=htons(port);
	memset(address.sin_zero,0,sizeof(address.sin_zero));

	if(SOCKET_ERROR == bind(sock,(const struct sockaddr*)&address,sizeof(struct sockaddr)) )
	{
		return false;
	}

	return true;
}

bool SetListen(SOCKET& sock,int number)
{
	if(SOCKET_ERROR == listen(sock,number) )
	{
		return false;
	}

	return true;
}

bool Communicate(SOCKET& srverSock)
{
	SOCKADDR_IN addrClient;
	SOCKET		newSock;
	HANDLE	hThread=NULL;
	int n=sizeof(struct sockaddr);
	bool flag=true;
	
	while(true)
	{
		newSock=accept(srverSock,( struct sockaddr*)&addrClient,&n);	
		
		if(newSock == INVALID_SOCKET)
		{
			cout<<"accept failed.\n";
			flag=false;
			break;
		}
	
		cout<<"client from "<<inet_ntoa(addrClient.sin_addr)<<":"<<ntohs(addrClient.sin_port)<<endl;

		hThread=CreateThread(NULL,0,ClientThread,(LPVOID)newSock,0,NULL);

		if(hThread==NULL)
		{
			cout<<"CreateThread failed.\n";
			flag=false;
			break;
		}

		CloseHandle(hThread);
	}

	closesocket(newSock);

	return flag;
}


bool CloseSocket(SOCKET& sock)
{
	if( closesocket(sock) == SOCKET_ERROR) 
		return false;
	return true;
}

void ExitWithErrorMessage(const string& errMsg)
{
	cout<<errMsg<<endl;
	system("pause");
	exit(1);
}

DWORD WINAPI ClientThread(LPVOID sockCliet)
{
	SOCKET sock=(SOCKET)sockCliet;
	char buffer[100]={0};
	int errCode;

	while(true)
	{
		memset(buffer,0,100);
		errCode=recv(sock,buffer,100,0);

		if(errCode==0 || errCode==SOCKET_ERROR)
		{
			cout<<"client exit.\n";
			break;
		}
		
		cout<<"message from client: "<<buffer<<endl;
		
		send(sock,"welcome.",strlen("welcome."),0);
	}

	return 0;
}


TCP Client

/************************************************************************/
/* 
准备步骤
#include <WINSOCK2.H>
#pragma     comment(lib, "ws2_32.lib ")

0:加载套接字库(WSAStartup())

1:创建套接字(socket());
  
2:向服务器发出连接请求(connect());
	
3:和服务器端进行通信(send()/recv());
	  
4:关闭套接字(closesocket())

5: 关闭加载的套接字库(WSACleanup())。

                                                                     */
/************************************************************************/

#include <WINSOCK2.H>
#include <windows.h>
#include <iostream>
#include <string>
using namespace std;
#pragma     comment(lib, "ws2_32.lib ")


//0 
bool LoadWSA();
//1
bool CreateSocket(SOCKET& sock,int type=SOCK_STREAM);
//2
bool ConnectToServer(SOCKET& sock,short port ,const char* strIp);
//3
bool Communicate(SOCKET& sock);
//4
bool CloseSocket(SOCKET& sock);
//5
void CloseWSA();

void ExitWithErrorMessage(const string& errMsg);


void main()
{
	cout<<"Start Client.\n";
	if(!LoadWSA() )
		ExitWithErrorMessage("LoadWSA  failed.");
	cout<<"LoadWSA Success.\n";
	
	SOCKET clietSock;
	
	if(!CreateSocket(clietSock) )
		ExitWithErrorMessage("create server socket failed.");
	cout<<"CreateSocket Success.\n";

	if(!ConnectToServer(clietSock,6000,"127.0.0.1") )
		ExitWithErrorMessage("ConnectToServer failed.");
	cout<<"ConnectToServer Success.\n";

	if(!Communicate(clietSock) )
		ExitWithErrorMessage("Communicate failed.");
	cout<<"Communicate Success.\n";

	if(! CloseSocket(clietSock) )
		ExitWithErrorMessage("CloseSocket failed.");
	cout<<"CloseSocket Success.\n";

	CloseWSA();
	cout<<"CloseWSA Success.\n";


}

bool LoadWSA()
{
	WSAData wsaData;
	
	if( 0 == WSAStartup(MAKEWORD(2,2),&wsaData) )
	{
		return true;
	}
	
	return false;
}

void CloseWSA()
{
	WSACleanup();
}

bool CreateSocket(SOCKET& sock,int type/* =SOCK_STREAM */)
{
	sock=socket(AF_INET,type,0);
	
	if(INVALID_SOCKET == sock)
	{
		return false;
	}
	
	return true;
}

bool ConnectToServer(SOCKET& sock,short port ,const char* strIp)
{
	SOCKADDR_IN address;
	
	address.sin_family=AF_INET;		
	address.sin_addr.s_addr=inet_addr(strIp);
	address.sin_port=htons(port);
	memset(address.sin_zero,0,sizeof(address.sin_zero));

	if(SOCKET_ERROR == connect(sock,(const struct sockaddr*)&address,sizeof(struct sockaddr)) )
	{
		return false;
	}
	
	return true;
}

bool Communicate(SOCKET& sock)
{
	bool flag=true;
	int errCode;
	char buffer[100]={0};

	while(true)
	{
		memset(buffer,0,100);
		cin.getline(buffer,100);
		errCode=send(sock,buffer,strlen(buffer),0);

		if(errCode==SOCKET_ERROR)
		{
			cout<<"send message error.\n";
			flag=false;
			break;
		}
	
		memset(buffer,0,100);
		recv(sock,buffer,100,0);
		cout<<buffer<<endl;
	}

	return flag;
}



void ExitWithErrorMessage(const string& errMsg)
{
	cout<<errMsg<<endl;
	system("pause");
	exit(1);
}

bool CloseSocket(SOCKET& sock)
{
	if( closesocket(sock)==SOCKET_ERROR )
		return false;

	return true;
}

 

2 upd编程

UDP Server

/************************************************************************/
/* 
准备步骤
#include <WINSOCK2.H>
#pragma     comment(lib, "ws2_32.lib ")

0: 加载套接字库(WSAStartup());

1:创建套接字(socket());
  
2:绑定套接字到一个IP地址和一个端口上(bind());
	
3:等待和接收数据(sendto()/recvfrom());
	  
4:关闭套接字(closesocket());
		
5: 关闭加载的套接字库(WSACleanup()).
                                                                     */
/************************************************************************/

#include <WINSOCK2.H>
#include <windows.h>
#include <iostream>
#include <string>
using namespace std;
#pragma     comment(lib, "ws2_32.lib ")


//0 
bool LoadWSA();
//1
bool CreateSocket(SOCKET& sock,int type=SOCK_DGRAM);
//2
bool BindSocket(SOCKET& sock,short port ,const char* strIp);
//4
bool Communicate(SOCKET& srverSock);
//5
bool CloseSocket(SOCKET& sock);
//6
void CloseWSA();

void ExitWithErrorMessage(const string& errMsg);


void main()
{
	if(! LoadWSA() )
		ExitWithErrorMessage("LoadWSA falid.");
	cout<<"LoadWSA success.\n";

	SOCKET serSocket;
	if(! CreateSocket(serSocket) )
		ExitWithErrorMessage("CreateSocket falid.");
	cout<<"CreateSocket success.\n";

	if(! BindSocket(serSocket,6000,"127.0.0.1") )
		ExitWithErrorMessage("BindSocket falid.");
	cout<<"BindSocket success.\n";
	
	while(! Communicate(serSocket) );
	cout<<"Communicate success.\n";

	if(! CloseSocket(serSocket) )
		ExitWithErrorMessage("CloseSocket falid.");
	cout<<"CloseSocket success.\n";

	CloseWSA();
} 


bool LoadWSA()
{
	WSAData wsaData;
	
	if( 0 == WSAStartup(MAKEWORD(2,2),&wsaData) )
	{
		return true;
	}
	
	return false;
}

void CloseWSA()
{
	WSACleanup();
}

bool CreateSocket(SOCKET& sock,int type)
{
	sock=socket(AF_INET,type,0);
	
	if(INVALID_SOCKET == sock)
	{
		return false;
	}
	
	return true;
}

bool BindSocket(SOCKET& sock,short port ,const char* strIp)
{
	SOCKADDR_IN address;
	
	address.sin_family=AF_INET;		
	address.sin_addr.s_addr =inet_addr(strIp);
	address.sin_port=htons(port);
	memset(address.sin_zero,0,sizeof(address.sin_zero));
	
	if(SOCKET_ERROR == bind(sock,(const struct sockaddr*)&address,sizeof(struct sockaddr)) )
	{
		return false;
	}
	
	return true;
}

bool Communicate(SOCKET& srverSock)
{
	bool flag =true;
	SOCKADDR_IN address;
	int n=sizeof(struct sockaddr);
	char buffer[100] = {0};

	if(recvfrom(srverSock,buffer, 100,0,(struct sockaddr*)&address,&n) ==SOCKET_ERROR )
		flag =false;

	if(flag)
		cout<<buffer;

	return flag;
}

void ExitWithErrorMessage(const string& errMsg)
{
	cout<<errMsg<<endl;
	system("pause");
	exit(1);
}

bool CloseSocket(SOCKET& sock)
{
	if( closesocket(sock)==SOCKET_ERROR )
		return false;
	
	return true;
}


TCP Client

/************************************************************************/
/* 
准备步骤
#include <WINSOCK2.H>
#pragma     comment(lib, "ws2_32.lib ")

0: 加载套接字库(WSAStartup());

1:创建套接字(socket());

2:等待和接收数据(sendto()/recvfrom());
	  
3:关闭套接字(closesocket());
		
4: ,关闭加载的套接字库(WSACleanup()).
                                                                     */
/************************************************************************/

#include <WINSOCK2.H>
#include <windows.h>
#include <iostream>
#include <string>
using namespace std;
#pragma     comment(lib, "ws2_32.lib ")


//0 
bool LoadWSA();
//1
bool CreateSocket(SOCKET& sock,int type=SOCK_DGRAM);
//2
bool Communicate(SOCKET& clientSock,short port ,const char* strIp);
//3
bool CloseSocket(SOCKET& sock);
//4
void CloseWSA();

void ExitWithErrorMessage(const string& errMsg);


void main()
{
	if(! LoadWSA() )
		ExitWithErrorMessage("LoadWSA falid.");
	cout<<"LoadWSA success.\n";

	SOCKET clientSocket;
	if(! CreateSocket( clientSocket) )
		ExitWithErrorMessage("CreateSocket falid.");
	cout<<"CreateSocket success.\n";

	if(! Communicate( clientSocket,6000,"127.0.0.1") )
		ExitWithErrorMessage("Communicate falid.");
	cout<<"Communicate success.\n";

	if(! CloseSocket( clientSocket) )
		ExitWithErrorMessage("CloseSocket falid.");
	cout<<"CloseSocket success.\n";

	CloseWSA();
} 


bool LoadWSA()
{
	WSAData wsaData;
	
	if( 0 == WSAStartup(MAKEWORD(2,2),&wsaData) )
	{
		return true;
	}
	
	return false;
}

void CloseWSA()
{
	WSACleanup();
}

bool CreateSocket(SOCKET& sock,int type)
{
	sock=socket(AF_INET,type,0);
	
	if(INVALID_SOCKET == sock)
	{
		return false;
	}
	
	return true;
}


bool Communicate(SOCKET& clientSock,short port ,const char* strIp)
{
	bool flag =true;
	SOCKADDR_IN address;
	int n=sizeof(struct sockaddr);

	address.sin_family=AF_INET;		
	address.sin_addr.s_addr=inet_addr(strIp);
	address.sin_port=htons(port);
	memset(address.sin_zero,0,sizeof(address.sin_zero));

	if( sendto(clientSock,"hello , I am from client message.", sizeof("hello , I am from server message."),
		0,(const struct sockaddr*)&address,sizeof(struct sockaddr) ) ==SOCKET_ERROR )
		   flag =false;

	return flag;
}

void ExitWithErrorMessage(const string& errMsg)
{
	cout<<errMsg<<endl;
	system("pause");
	exit(1);
}

bool CloseSocket(SOCKET& sock)
{
	if( closesocket(sock)==SOCKET_ERROR )
		return false;
	
	return true;
}


 

评论 3
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值