2009年7月21日 星期二

Windows Socket Server/Client with Visual C++

/* Blocking Sockets in TCP/IP (The Server) */
#include <iostream>
#include <string>
#include <string.h>
#include <winsock2.h>
#pragma comment(lib,"ws2_32.lib")
#define WSA_VERSION MAKEWORD(2, 2) // using winsock 2.2

using namespace std;

class TcpServer{
public:
 class InitSocketError{};
 class CreateSocketError{};
 class BindSocketError{};

 TcpServer()
 {
  initWinsock();
  _socket = tcpSocket();
  listenSocket(8888);
 }

 TcpServer(u_short port)
 {
  initWinsock();
  _socket = tcpSocket();
  listenSocket(port);
 }

 ~TcpServer()
 {
  endSocket();
 }

 SOCKET getSocket(){ return _socket; }
 void sendMessage();
private:
 SOCKET _socket;

 bool initWinsock();
 SOCKET tcpSocket();
 void listenSocket(u_short);
 void endSocket();

};

bool TcpServer::initWinsock()
{
 // Initialise Winsock
 WSADATA WsaData = { 0 };
 if(WSAStartup(WSA_VERSION, &WsaData) != 0)
 {
  // Tell the user that we could not find a usable WinSock DLL.
  if(LOBYTE(WsaData.wVersion) != LOBYTE(WSA_VERSION) ||
   HIBYTE(WsaData.wVersion) != HIBYTE(WSA_VERSION)){
    throw InitSocketError();
  }
  WSACleanup();
  system("PAUSE");
  return false;
 }
 return true;
}

SOCKET TcpServer::tcpSocket()
{
 _socket = socket(AF_INET, SOCK_STREAM, IPPROTO_TCP);
 if(_socket==INVALID_SOCKET)
 {
  throw CreateSocketError();
  WSACleanup();
  system("PAUSE");
  return 0;
 }
 return _socket;
}

void TcpServer::listenSocket(u_short port)
{
 SOCKADDR_IN serverInf;
 serverInf.sin_family=AF_INET;
 serverInf.sin_addr.s_addr=INADDR_ANY;
 serverInf.sin_port=htons(port);

 if(bind(_socket,(SOCKADDR*)(&serverInf),sizeof(serverInf))==SOCKET_ERROR)
 {
  throw BindSocketError();
  WSACleanup();
  system("PAUSE");
  return;
 }
 listen(_socket,1);
}

void TcpServer::sendMessage()
{
 SOCKET TempSock=SOCKET_ERROR;
 while(TempSock==SOCKET_ERROR)
 {
  cout<<"Waiting for incoming connections...\r\n";
  TempSock=accept(_socket,NULL,NULL);
 }
 _socket=TempSock;

 cout<<"Client connected!\r\n\r\n";

 char *szMessage="Welcome to the server!\r\n";
 send(_socket, szMessage, strlen(szMessage), 0);
}


void TcpServer::endSocket()
{
 // Shutdown our socket
 shutdown(_socket, SD_SEND);
 // Close our socket entirely
 closesocket(_socket);
 // Cleanup Winsock
 WSACleanup();
}

int main()
{
 try{
  TcpServer *ts1 = new TcpServer(8888);
  ts1->sendMessage();  
  system("PAUSE");
 }catch(TcpServer::InitSocketError){
  cout<<"Winsock error - Winsock initialization failed\r\n";
  system("PAUSE");
 }catch(TcpServer::CreateSocketError){
  cout<<"Winsock error - Socket creation Failed, ec: "<<WSAGetLastError()<<endl;
  system("PAUSE");
 }catch(TcpServer::BindSocketError){
  std::cout<<"Unable to bind socket!\r\n";
  system("PAUSE");
 }

 return 0;
}
/* Blocking Sockets in TCP/IP (The Client) */
#include <iostream>
#include <string>
#include <winsock2.h>
#pragma comment(lib,"ws2_32.lib")
#define WSA_VERSION MAKEWORD(2, 2) // using winsock 2.2

using namespace std;


class TcpClient
{
public:
 class InitSocketError{};
 class CreateSocketError{};
 class GetHostNameError{};
 class ConnectSocketError{};

 TcpClient()
 {
  string hostname = "localhost";
  initWinsock();
  _socket = tcpSocket();
  connectSocket(hostname, 8888);
 }

 TcpClient(string hostname, u_short hostport)
 {
  initWinsock();
  _socket = tcpSocket();
  connectSocket(hostname, hostport);
 }

 ~TcpClient()
 {
  endSocket();
 }

 SOCKET getSocket() { return _socket; }
 void recevMessage();

private:
 SOCKET _socket;

 bool initWinsock();
 SOCKET tcpSocket();
 bool connectSocket(string&, u_short);
 void endSocket();
};

bool TcpClient::initWinsock()
{
 // Initialise Winsock
 WSADATA WsaData = { 0 };
 if(WSAStartup(WSA_VERSION, &WsaData) != 0)
 {
  // Tell the user that we could not find a usable WinSock DLL.
  if(LOBYTE(WsaData.wVersion) != LOBYTE(WSA_VERSION) ||
   HIBYTE(WsaData.wVersion) != HIBYTE(WSA_VERSION)){
    throw InitSocketError();
  }

  WSACleanup();
  system("PAUSE");
  return false;
 }
 return true;
}

SOCKET TcpClient::tcpSocket()
{
 SOCKET tsocket = socket(AF_INET, SOCK_STREAM, IPPROTO_TCP);
 if(tsocket == INVALID_SOCKET)
 {
  throw CreateSocketError();
  WSACleanup();
  system("PAUSE");
  return 0;
 }
 return tsocket;
}

bool TcpClient::connectSocket(string& hostname, u_short hostport)
{
 // Resolve IP address for hostname
 struct hostent *host;
 if((host=gethostbyname(hostname.c_str()))==NULL)
 {
  throw GetHostNameError();
  WSACleanup();
  system("PAUSE");
  return false;
 }

 // Setup our socket address structure
 SOCKADDR_IN SockAddr;
 SockAddr.sin_port=htons(hostport);
 SockAddr.sin_family=AF_INET;
 SockAddr.sin_addr.s_addr=*((unsigned long*)host->h_addr);

 // Attempt to connect to server
 if(connect(_socket, (SOCKADDR*)(&SockAddr), sizeof(SockAddr))!=0)
 {
  throw ConnectSocketError();
  WSACleanup();
  cout<<"exe\n";
  system("PAUSE");
  return false;
 }
 return true;
}

void TcpClient::recevMessage()
{
 // Display message from server
 char buffer[1000];
 memset(buffer,0,999);
 int inDataLength=recv(_socket, buffer, 1000, 0);
 cout<<buffer;
}

void TcpClient::endSocket()
{
 // Shutdown our socket
 shutdown(_socket, SD_SEND);
 // Close our socket entirely
 closesocket(_socket);
 // Cleanup Winsock
 WSACleanup();
}


int main()
{
 try{

  TcpClient *tc2 = new TcpClient("smtp.gmail.com", 587);
  tc2->recevMessage();

  TcpClient *tc1 = new TcpClient();
  tc1->recevMessage();

  system("PAUSE");
 }catch(TcpClient::InitSocketError){
  cout<<"Winsock error - Winsock initialization failed\r\n";
  system("PAUSE");
 }catch(TcpClient::CreateSocketError){
  cout<<"Winsock error - Socket creation Failed, ec: "<<WSAGetLastError()<<endl;
  system("PAUSE");
 }catch(TcpClient::GetHostNameError){
  cout<<"Failed to resolve hostname.\r\n";
  system("PAUSE");
 }catch(TcpClient::ConnectSocketError){
  std::cout<<"Failed to establish connection with server\r\n";
  system("PAUSE");
 }
 return 0;
}
/**********************************************
Non-Blocking Sockets in TCP/IP (The Server)
1) Initialise Winsock
2) Create a Socket
3) Fill out a SOCKADDR_IN struct
4) Listen on our socket
5) Accept a connection from the client 
***********************************************/

#include <iostream>
#include <winsock2.h>
#pragma comment(lib,"ws2_32.lib")
#define WSA_VERSION MAKEWORD(2, 2) // using winsock 2.2

int main()
{
 WSADATA WsaDat;
 if(WSAStartup(WSA_VERSION, &WsaDat)!=0)
 {
  std::cout<<"WSA Initialization failed!\r\n";
  WSACleanup();
  system("PAUSE");
  return 0;
 }

 SOCKET Socket=socket(AF_INET,SOCK_STREAM,IPPROTO_TCP);
 if(Socket==INVALID_SOCKET)
 {
  std::cout<<"Socket creation failed.\r\n";
  WSACleanup();
  system("PAUSE");
  return 0;
 }

 SOCKADDR_IN serverInf;
 serverInf.sin_family=AF_INET;
 serverInf.sin_addr.s_addr=INADDR_ANY;
 serverInf.sin_port=htons(8888);

 if(bind(Socket,(SOCKADDR*)(&serverInf),sizeof(serverInf))==SOCKET_ERROR)
 {
  std::cout<<"Unable to bind socket!\r\n";
  WSACleanup();
  system("PAUSE");
  return 0;
 }

 listen(Socket,1);

 SOCKET TempSock=SOCKET_ERROR;
 while(TempSock==SOCKET_ERROR)
 {
  std::cout<<"Waiting for incoming connections...\r\n";
  TempSock=accept(Socket,NULL,NULL);
 }

 // If iMode!=0, non-blocking mode is enabled.
 u_long iMode=1;
 ioctlsocket(Socket,FIONBIO,&iMode);

 Socket=TempSock;
 std::cout<<"Client connected!\r\n\r\n";

 // Main loop
 for(;;)
 {
  char *szMessage="Welcome to the server!\r\n";
  send(Socket,szMessage,strlen(szMessage),0);

  int nError=WSAGetLastError();
  if(nError!=WSAEWOULDBLOCK&&nError!=0)
  {
   std::cout<<"Winsock error code: "<<nError<<"\r\n";
   std::cout<<"Client disconnected!\r\n";

   // Shutdown our socket
   shutdown(Socket,SD_SEND);

   // Close our socket entirely
   closesocket(Socket);

   break;
  }

  Sleep(1000);
 }

 WSACleanup();
 system("PAUSE");
 return 0;
}
/* Non-Blocking Sockets in TCP/IP (The Client) */
#include <iostream>
#include <winsock2.h>
#pragma comment(lib,"ws2_32.lib")

#define WSA_VERSION MAKEWORD(2, 2) // using winsock 2.2
using namespace std;

class NonBlockTcpClient
{
public:
 class CreateSocketError{};
 class GetHostNameError{};
 class ConnectSocketError{};
 NonBlockTcpClient()
 {
  string hostname = "localhost";
  _socket = tcpSocket();
  connectSocket(hostname, 8888);
 }
 NonBlockTcpClient(string hostname, u_short hostport)
 {
  _socket = tcpSocket();
  connectSocket(hostname, hostport);
 }
 void sendMessage();
private:
 SOCKET _socket;

 SOCKET tcpSocket();
 bool connectSocket(string&, u_short);
};


SOCKET NonBlockTcpClient::tcpSocket()
{
 // Create our socket

 SOCKET Socket = socket(AF_INET, SOCK_STREAM, IPPROTO_TCP);
 if(Socket==INVALID_SOCKET)
 {
  throw CreateSocketError(); 
  return 0;
 }
 return Socket;
}

bool NonBlockTcpClient::connectSocket(string& hostname, u_short hostport)
{
 // Resolve IP address for hostname
 struct hostent *host;
 if((host=gethostbyname(hostname.c_str()))==NULL)
 {
  throw GetHostNameError();
  return false;
 }

 // Setup our socket address structure
 SOCKADDR_IN SockAddr;
 SockAddr.sin_port=htons(hostport);
 SockAddr.sin_family=AF_INET;
 SockAddr.sin_addr.s_addr=*((unsigned long*)host->h_addr);

 // Attempt to connect to server
 if(connect(_socket,(SOCKADDR*)(&SockAddr),sizeof(SockAddr))!=0)
 {
  throw ConnectSocketError();
  return false;
 }

 // If iMode!=0, non-blocking mode is enabled.
 u_long iMode=1;
 ioctlsocket(_socket,FIONBIO,&iMode);
 return true;
}

void NonBlockTcpClient::sendMessage()
{
 // Main loop
 for(;;)
 {
  // Display message from server
  char buffer[1000];
  memset(buffer,0,999);
  int inDataLength=recv(_socket,buffer,1000,0);
  std::cout<<buffer;

  int nError=WSAGetLastError();
  if(nError!=WSAEWOULDBLOCK&&nError!=0)
  {
   std::cout<<"Winsock error code: "<<nError<<"\r\n";
   std::cout<<"Server disconnected!\r\n";
   // Shutdown our socket
   shutdown(_socket,SD_SEND);

   // Close our socket entirely
   closesocket(_socket);

   break;
  }
  Sleep(1000);
 }
}

int main(void)
{
 /* initialize winsock */
 WSADATA WsaDat;
 if(WSAStartup(WSA_VERSION, &WsaDat)!=0)
 {
  std::cout<<"Winsock error - Winsock initialization failed\r\n";
  WSACleanup();
  system("PAUSE");
  return 0;
 }

 try{

  //NonBlockTcpClient *nbtc = new NonBlockTcpClient("smtp.gmail.com", 587); 
  //nbtc->sendMessage();
  NonBlockTcpClient *nbtcl = new NonBlockTcpClient(); 
  nbtcl->sendMessage();
 }catch(NonBlockTcpClient::CreateSocketError){
  cout<<"Winsock error - Socket creation Failed!\r\n";
  WSACleanup();
  system("PAUSE");
 }catch(NonBlockTcpClient::GetHostNameError){
  cout<<"Failed to resolve hostname.\r\n";
  WSACleanup();
  system("PAUSE");
 }catch(NonBlockTcpClient::ConnectSocketError){
  cout<<"Failed to establish connection with server\r\n";
  WSACleanup();
  system("PAUSE");
 }

 /* clean winsock */
 WSACleanup();
 system("PAUSE");
 return 0;
}

0 意見: