使用C++实现Win32平台的TCP/IP网络编程,练习socket的使用。
服务端:
#include <iostream>
#include <WinSock2.h>
const unsigned short LISTEN_PORT = 8700;
int main(int argc, char* argv[])
{
using namespace std;
WORD wVersionRequested = MAKEWORD(1, 1);
WSADATA wsaData;
int err = WSAStartup(wVersionRequested, &wsaData);
if ( 0 != err )
{
cout<<"WSAStartup failed. return: "<<err<<endl;
return -1;
}
if ( wsaData.wVersion != wVersionRequested )
{
cout<<"wsaData.wVersion: "<<wsaData.wVersion<<" is not equal to wVersionRequested: "<<wVersionRequested<<endl;
WSACleanup();
return -2;
}
SOCKET sock = socket(AF_INET, SOCK_STREAM, 0);
if ( INVALID_SOCKET == sock )
{
cout<<"socket error: "<<WSAGetLastError()<<endl;
return -3;
}
SOCKADDR_IN addr_server;
addr_server.sin_family = AF_INET;
addr_server.sin_port = htons(LISTEN_PORT);
addr_server.sin_addr.S_un.S_addr = htonl(INADDR_ANY);
err = bind(sock, (SOCKADDR*)&addr_server, sizeof(addr_server));
if ( SOCKET_ERROR == err )
{
cout<<"bind error: "<<WSAGetLastError()<<endl;
return -4;
}
err = listen(sock, SOMAXCONN);
if ( SOCKET_ERROR == err )
{
cout<<"listen error: "<<WSAGetLastError()<<endl;
return -5;
}
cout<<"Start listening on port "<<LISTEN_PORT<<endl;
SOCKADDR_IN addr_client;
int addrlen = sizeof(addr_client);
while (true)
{
SOCKET sock_con = accept(sock, (SOCKADDR*)&addr_client, &addrlen);
if ( INVALID_SOCKET != sock_con )
{
cout<<inet_ntoa(addr_client.sin_addr)<<":"<<ntohs(addr_client.sin_port)<<" connected!"<<endl;
char recv_buf[256];
char send_buf[512];
while (true)
{
err = recv(sock_con, recv_buf, sizeof(recv_buf), 0);
if ( err <= 0 )
{
cout<<"recv error: "<<WSAGetLastError()<<endl;
break;
}
sprintf(send_buf, "%s:%d said: %s", inet_ntoa(addr_client.sin_addr), ntohs(addr_client.sin_port), recv_buf);
cout<<send_buf<<endl;
sprintf(send_buf, "you said: %s", recv_buf);
err = send(sock_con, send_buf, strlen(send_buf) + 1, 0);
if ( SOCKET_ERROR == err )
{
cout<<"send error: "<<WSAGetLastError()<<endl;
break;
}
}
cout<<inet_ntoa(addr_client.sin_addr)<<":"<<ntohs(addr_client.sin_port)<<" left!"<<endl;
err = closesocket(sock_con);
if ( SOCKET_ERROR == err )
{
cout<<"closesocket error: "<<WSAGetLastError()<<endl;
}
}
else
{
cout<<"accept error: "<<WSAGetLastError()<<endl;
}
}
WSACleanup();
return 0;
}
客户端:
#include <iostream>
#include <WinSock2.h>
const char* SERVER_IP = "127.0.0.1";
const unsigned short SERVER_PORT = 8700;
int main(int argc, char* argv[])
{
using namespace std;
WORD wVersionRequested = MAKEWORD(1, 1);
WSADATA wsaData;
int err = WSAStartup(wVersionRequested, &wsaData);
if ( 0 != err )
{
cout<<"WSAStartup failed. return: "<<err<<endl;
return -1;
}
if ( wsaData.wVersion != wVersionRequested )
{
cout<<"wsaData.wVersion: "<<wsaData.wVersion<<" is not equal to wVersionRequested: "<<wVersionRequested<<endl;
WSACleanup();
return -2;
}
SOCKET sock = socket(AF_INET, SOCK_STREAM, 0);
if ( INVALID_SOCKET == sock )
{
cout<<"socket error: "<<WSAGetLastError()<<endl;
return -3;
}
SOCKADDR_IN addr_server;
addr_server.sin_family = AF_INET;
addr_server.sin_port = htons(SERVER_PORT);
addr_server.sin_addr.S_un.S_addr = inet_addr(SERVER_IP);
err = connect(sock, (SOCKADDR*)&addr_server, sizeof(addr_server));
if ( SOCKET_ERROR == err )
{
cout<<"connect error: "<<WSAGetLastError()<<endl;
return -4;
}
cout<<"Connection established."<<endl;
char send_buf[256];
char recv_buf[512];
while (true)
{
cin.getline(send_buf, 256);
cin.clear(); //NOTE: If not clear, when input size overflow, getline will fail the next time.
if ( 0 == stricmp(send_buf, "quit") || 0 == stricmp(send_buf, "exit") )
break;
err = send(sock, send_buf, strlen(send_buf) + 1, 0);
if ( SOCKET_ERROR == err )
{
cout<<"send error: "<<WSAGetLastError()<<endl;
}
err = recv(sock, recv_buf, sizeof(recv_buf), 0);
if ( err <= 0 )
{
cout<<"recv error: "<<WSAGetLastError()<<endl;
}
cout<<recv_buf<<endl;
}
err = closesocket(sock);
if ( SOCKET_ERROR == err )
{
cout<<"closesocket error: "<<WSAGetLastError()<<endl;
}
WSACleanup();
return 0;
}