2007年4月2日星期一

一个简易的客户端与服务端代码(阻塞模式)

一个简易的客户端与服务端代码(阻塞模式)
//+++++++++++=CLIENT.CPP+++++++++++++++++++
#include
//#include
#include "winsock.h"
//#include "stdlib.h"
//#include
/*#include
#pragma comment(lib, "ws2_32.lib")*/
#pragma comment (lib,"wsock32.lib")
using namespace std;

// SOCKET client_socket; //用于返回与客户连接的 SOCKET句柄 变量
// sockaddr_in client_addr; //用于返回与客户地址的缓冲区变量
// int client_addr_len = sizeof(client_addr); //用于返回与客户地址的缓冲区长度的变量
char rev_buff[1000];
int main()
{
WSADATA wsd;
/* 初始化WinSock1.1 WSAStartup() */
if (WSAStartup(0x101, &wsd)) //WSAStartup(0x101, &wsd) 成功返回0,即false
{
printf("WinSocket库加载失败!\n");
return -1;
}
cout<<"WinSocket库加载成功,返回如下信息: " << "\n"
<<"******************************************************\n"
<<"一个进程可以打开的最大套接口数目:" << "\t"
<< wsd.iMaxSockets << "\n"
<<"发送或接收的最大UDP数据报的大小:" << "\t"
<< wsd.iMaxUdpDg << "\n"
<<"指向厂商规定数据结构的远指针:" << "\t\t"
<< int(wsd.lpVendorInfo)<< "\n"
<<"厂商描述字符串:" << "\t\t\t"
<< wsd.szDescription << "\n"
<<"状态和配置信息字符串:" << "\t\t\t"
<< wsd.szSystemStatus << "\n"
<<"现有winsock库最高版本:" << "\t\t\t"
<< int(LOBYTE(wsd.wHighVersion)) << "."<< int(HIBYTE(wsd.wHighVersion))<<"\n" //现有winsock库最高版本
<<"准备使用的winsock版本:" << "\t\t\t"
<< int(LOBYTE(wsd.wVersion)) << "."<< int(HIBYTE(wsd.wVersion)) << "\n"
<<"******************************************************\n"
<<"\n"; //准备使用的winsock版本

///* 创建TCP套接字 SOCKET()*/
SOCKET s; //声明一个 SOCKET句柄 变量 s
s = socket(AF_INET,SOCK_STREAM,0) ; //socket()函数调用返回一个TCP套接字句柄
cout<<"已创建一个套接字,句柄:\t\t"<< s <<"\n\n";
//int error = 0; //接受调用函数的返回值,判断错误。

//连接服务器 connect()
int server_port = 5555;
sockaddr_in server_addr; //声明一个sockaddr_in类型的结构体,并填充
server_addr.sin_family = AF_INET;
server_addr.sin_port = htons(5555);
server_addr.sin_addr.S_un.S_addr = inet_addr("127.0.0.1");
if (connect(s,(sockaddr *)(&server_addr),sizeof(server_addr))==SOCKET_ERROR) //(sockaddr *)(&server_addr)此处小括号为优先级运算限定,明示一个sockaddr类型的指针.SOCKET_ERROR = -1
{
//connect()出错时的处理
if (GetLastError() != WSAEWOULDBLOCK)
{
cout<<"WSAEWOULDBLOCK错误,请确认服务器已经打开,并在正确端口工作!\n\n";
closesocket(s);
system("PAUSE");
return -2;
}
else
{
cout<<"未知错误,\n\n";
closesocket(s);
system("PAUSE");
return -3;
}
}
//connect()成功后的代码
else
{
cout<<"与服务器连接成功!\n\n"
<<"连接协议为:\t\t\t\t"<<"AF_INET("<< server_addr.sin_family<<")"<<"\n"
<<"目的端口为:\t\t\t\t"<< htons(server_addr.sin_port)<<"\n"
<<"远方服务器地址为:\t\t\t"<< inet_ntoa(server_addr.sin_addr)<<"\n\n"; // inet_ntoa()把server_addr.sin_addr转换成字符串
//inet_addr()把字符串转换成和server_addr.sin_addr一样的类型
}

//接收服务器信息
//cout<<"等待连接中......\n";
memset(rev_buff,0,sizeof(rev_buff));
if (recv(s,rev_buff,sizeof(rev_buff),0) == SOCKET_ERROR)
{
cout<<"Recv接收错误!\n\n";
closesocket(s);
system("PAUSE");
return -4;
}
else
{
cout<<"Recv接收成功!\n";
cout<< rev_buff<<"\n";

}

/* 关闭TCP套接字 closesocket() */
if (closesocket(s)== SOCKET_ERROR)
{
cout<<"closesocket()错误";
return -4;
}
else
{
cout<<"套接字closesocket()成功!\n\n";
}

/* 释放WinSock1.1 */
if (WSACleanup()==0)
{ ;
cout<<"WinSocket库成功释放!\n\n";
}
system("PAUSE");
return 0;

}





//+++++++++++=SERVER.CPP+++++++++++++++++++

#include
//#include
#include "winsock.h"
//#include "stdlib.h"
#include
/*#include
#pragma comment(lib, "ws2_32.lib")*/
#pragma comment (lib,"wsock32.lib")
using namespace std;

SOCKET client_socket; //用于返回与客户连接的 SOCKET句柄 变量
sockaddr_in client_addr; //用于返回与客户地址的缓冲区变量
int client_addr_len = sizeof(client_addr); //用于返回与客户地址的缓冲区长度的变量
string send_buff;
int main()
{
//memset(send_buff,0,sizeof(send_buff));
send_buff = "人生是一场倾盆大雨,命运则是一把漏洞百出的雨伞";


WSADATA wsd;
/* 初始化WinSock1.1 WSAStartup() */
if (WSAStartup(0x101, &wsd)) //WSAStartup(0x101, &wsd) 成功返回0,即false
{
printf("WinSocket库加载失败!\n");
return -1;
}
cout<<"WinSocket库加载成功,返回如下信息: " << "\n"
<<"******************************************************\n"
<<"一个进程可以打开的最大套接口数目:" << "\t"
<< wsd.iMaxSockets << "\n"
<<"发送或接收的最大UDP数据报的大小:" << "\t"
<< wsd.iMaxUdpDg << "\n"
<<"指向厂商规定数据结构的远指针:" << "\t\t"
<< int(wsd.lpVendorInfo)<< "\n"
<<"厂商描述字符串:" << "\t\t\t"
<< wsd.szDescription << "\n"
<<"状态和配置信息字符串:" << "\t\t\t"
<< wsd.szSystemStatus << "\n"
<<"现有winsock库最高版本:" << "\t\t\t"
<< int(LOBYTE(wsd.wHighVersion)) << "."<< int(HIBYTE(wsd.wHighVersion))<<"\n" //现有winsock库最高版本
<<"准备使用的winsock版本:" << "\t\t\t"
<< int(LOBYTE(wsd.wVersion)) << "."<< int(HIBYTE(wsd.wVersion)) << "\n"
<<"******************************************************\n"
<<"\n"; //准备使用的winsock版本

/* 创建TCP套接字 SOCKET()*/
SOCKET s; //声明一个 SOCKET句柄 变量 s
s = socket(AF_INET,SOCK_STREAM,0) ; //socket()函数调用返回一个TCP套接字句柄
cout<<"已创建一个套接字,句柄:\t\t"<< s <<"\n";
//int error = 0; //接受调用函数的返回值,判断错误。
/* 在服务端为TCP套接字绑定一个已知地址 BIND() */
int local_port;
sockaddr_in localaddr; //声明一个sockaddr_in类型的结构体,并填充
local_port = 5555;
localaddr.sin_family = AF_INET;
localaddr.sin_port = htons(local_port);
localaddr.sin_addr.S_un.S_addr = htonl(INADDR_ANY);
/* 为什么端口是用htons而ip地址是用htonl?
htonl()表示将32位的主机字节顺序转化为32位的网络字节顺序
htons()表示将16位的主机字节顺序转化为16位的网络字节顺序
i p地址是32位的端口号是16位的 */
if (bind(s,(sockaddr *)(&localaddr),sizeof(localaddr))!=SOCKET_ERROR) //(sockaddr *)(&localaddr)此处小括号为优先级运算限定,明示一个sockaddr类型的指针.SOCKET_ERROR = -1
{
cout<<"已绑定协议为:\t\t\t\t"<<"AF_INET("<< localaddr.sin_family<<")"<<"\n"
<<"已绑定端口为:\t\t\t\t"<< local_port<<"\n"
<<"已绑定地址为:\t\t\t\t"<< inet_ntoa(localaddr.sin_addr)<<"\n\n"; // inet_ntoa()把server_addr.sin_addr转换成字符串
} //inet_addr()把字符串转换成和server_addr.sin_addr一样的类型
else
{
closesocket(s);
return -2;
}


/* 在服务端指示TCP套接字S进入监听连接 LISTEN() */
if (listen(s,5)== SOCKET_ERROR)
{
cout<<"LISTEN()错误";
closesocket(s);
return -3;
}
else
{
cout<<"套接字LISTEN()成功,句柄:\t\t"<< s <<"\n\n";
}


/* 循环调用ACCEPT()接受连接请求 */
while(true)
{
cout<<"等待连接中......\n\n";
client_socket = accept(s,(sockaddr *)(&client_addr),&client_addr_len); //接受一个连接请求,并返回一个同客户端交互的socket给变量client_socket
if (client_socket == INVALID_SOCKET)
{
cout<<"ACCEPT()错误";
closesocket(s);
return -4;
}
cout<<"接收到客户端连接,IP为:\t\t"<< inet_ntoa(client_addr.sin_addr) <<"\n\n";
send(client_socket,&send_buff[0],send_buff.length(),0); //信息发送
closesocket(client_socket); //信息发送完毕后即关闭与客户的连接
cout<<"信息发送完毕\n\n";

//只相应一次连接即关闭程序
closesocket(s);
WSACleanup();
system("PAUSE");
return 1;
}


/* 关闭TCP套接字 closesocket() */
if (closesocket(s)== SOCKET_ERROR)
{
cout<<"closesocket()错误";
return -4;
}
else
{
cout<<"套接字closesocket()成功!\n\n";
}

/* 释放WinSock1.1 */
if (WSACleanup()==0)
{ ;
cout<<"WinSocket库成功释放!\n\n";
}
system("PAUSE");
return 0;

}

没有评论: