⭐ 欢迎来到虫虫下载站! | 📦 资源下载 📁 资源专辑 ℹ️ 关于我们
⭐ 虫虫下载站

📄 basic-server.cpp

📁 SDK FAQ集
💻 CPP
字号:
/***********************************************************************
 basic-server.cpp - Implements a fairly basic single-threaded Winsock 
 	server program that waits for a connection, accepts it, echoes back
	any data it receives, and then goes back to listening when the
	client drops the connection.

 Compiling:
 	VC++: cl -GX basic-server.cpp main.cpp ws-util.cpp wsock32.lib
	BC++: bcc32 basic-server.cpp main.cpp ws-util.cpp
	
 This program is hereby released into the public domain.  There is
 ABSOLUTELY NO WARRANTY WHATSOEVER for this product.  Caveat hacker.
***********************************************************************/

#include <iostream.h>
#include <winsock2.h>
#include "ws-util.h"


//// Constants /////////////////////////////////////////////////////////

const int kBufferSize = 1024;
		

//// Prototypes ////////////////////////////////////////////////////////

SOCKET SetUpListener(const char* pcAddress, int nPort);
SOCKET AcceptConnection(SOCKET ListeningSocket, sockaddr_in& sinRemote);
bool EchoIncomingPackets(SOCKET sd);


//// DoWinsock /////////////////////////////////////////////////////////
// The module's driver function -- we just call other functions and
// interpret their results.

int DoWinsock(const char* pcAddress, int nPort)
{
	cout << "Establishing the listener..." << endl;
	SOCKET ListeningSocket = SetUpListener(pcAddress, htons(nPort));
	if (ListeningSocket == INVALID_SOCKET) {
		cout << endl << WSAGetLastErrorMessage("establish listener") << 
				endl;
		return 3;
	}

	while (1) {
		cout << "Waiting for a connection..." << flush;
		sockaddr_in sinRemote;
		SOCKET sd = AcceptConnection(ListeningSocket, sinRemote);
		if (sd != INVALID_SOCKET) {
			cout << "Accepted connection from " <<
					inet_ntoa(sinRemote.sin_addr) << "." << endl;
		}
		else {
			cout << endl << WSAGetLastErrorMessage(
					"accept connection") << endl;
			return 3;
		}
		
		if (EchoIncomingPackets(sd)) {
			// Successfully bounced all connections back to client,
			// so close the connection down gracefully.
			cout << "Shutting connection down..." << flush;
			if (ShutdownConnection(sd)) {
				cout << "Connection is down." << endl;
			}
			else {
				cout << endl << WSAGetLastErrorMessage(
						"shutdown connection") << endl;
				return 3;
			}
		}
		else {
			cout << endl << WSAGetLastErrorMessage(
					"echo incoming packets") << endl;
			return 3;
		}
	}

	return 0;
}


//// SetUpListener /////////////////////////////////////////////////////
// Sets up a listener on the given interface and port, returning the
// listening socket if successful; if not, returns INVALID_SOCKET.

SOCKET SetUpListener(const char* pcAddress, int nPort)
{
	u_long nInterfaceAddr = inet_addr(pcAddress);
	if (nInterfaceAddr != INADDR_NONE) {
		SOCKET sd = socket(AF_INET, SOCK_STREAM, 0);
		if (sd != INVALID_SOCKET) {
			sockaddr_in sinInterface;
			sinInterface.sin_family = AF_INET;
			sinInterface.sin_addr.s_addr = nInterfaceAddr;
			sinInterface.sin_port = nPort;
			if (bind(sd, (sockaddr*)&sinInterface, 
					sizeof(sockaddr_in)) != SOCKET_ERROR) {
				listen(sd, SOMAXCONN);
				return sd;
			}
		}
	}

	return INVALID_SOCKET;
}


//// AcceptConnection //////////////////////////////////////////////////
// Waits for a connection on the given socket.  When one comes in, we
// return a socket for it.  If an error occurs, we return 
// INVALID_SOCKET.

SOCKET AcceptConnection(SOCKET ListeningSocket, sockaddr_in& sinRemote)
{
	int nAddrSize = sizeof(sinRemote);
	return accept(ListeningSocket, (sockaddr*)&sinRemote, &nAddrSize);
}


//// EchoIncomingPackets ///////////////////////////////////////////////
// Bounces any incoming packets back to the client.  We return false
// on errors, or true if the client closed the socket normally.

bool EchoIncomingPackets(SOCKET sd)
{
	// Read data from client
	char acReadBuffer[kBufferSize];
	int nReadBytes;
	do {
		nReadBytes = recv(sd, acReadBuffer, kBufferSize, 0);
		if (nReadBytes > 0) {
			cout << "Received " << nReadBytes << 
					" bytes from client." << endl;
		
			int nSentBytes = 0;
			while (nSentBytes < nReadBytes) {
				int nTemp = send(sd, acReadBuffer + nSentBytes,
						nReadBytes - nSentBytes, 0);
				if (nTemp > 0) {
					cout << "Sent " << nTemp << 
							" bytes back to client." << endl;
					nSentBytes += nTemp;
				}
				else if (nTemp == SOCKET_ERROR) {
					return false;
				}
				else {
					// Client closed connection before we could reply to
					// all the data it sent, so bomb out early.
					cout << "Peer unexpectedly dropped connection!" << 
							endl;
					return true;
				}
			}
		}
		else if (nReadBytes == SOCKET_ERROR) {
			return false;
		}
	} while (nReadBytes != 0);

	cout << "Connection closed by peer." << endl;
	return true;
}


⌨️ 快捷键说明

复制代码 Ctrl + C
搜索代码 Ctrl + F
全屏模式 F11
切换主题 Ctrl + Shift + D
显示快捷键 ?
增大字号 Ctrl + =
减小字号 Ctrl + -