mirror of
https://github.com/reactos/reactos.git
synced 2025-08-06 03:33:48 +00:00
- Tree cleanups proposed on the mailing list. Move all non-Core OS modules to rosapps. Tests were already moved by Fireball to rostests.
svn path=/trunk/; revision=26033
This commit is contained in:
parent
ad07a1e58f
commit
1e3d5d70e9
420 changed files with 78215 additions and 0 deletions
344
rosapps/roshttpd/common/socket.cpp
Normal file
344
rosapps/roshttpd/common/socket.cpp
Normal file
|
@ -0,0 +1,344 @@
|
|||
/*
|
||||
* COPYRIGHT: See COPYING in the top level directory
|
||||
* PROJECT: ReactOS HTTP Daemon
|
||||
* FILE: socket.cpp
|
||||
* PURPOSE: Socket classes
|
||||
* PROGRAMMERS: Casper S. Hornstrup (chorns@users.sourceforge.net)
|
||||
* REVISIONS:
|
||||
* CSH 01/09/2000 Created
|
||||
*/
|
||||
#include <socket.h>
|
||||
#include <string.h>
|
||||
#include <error.h>
|
||||
#include <iterator.h>
|
||||
|
||||
// ***************************** CSocket *****************************
|
||||
|
||||
// Default constructor
|
||||
CSocket::CSocket()
|
||||
{
|
||||
Active = FALSE;
|
||||
Event = WSA_INVALID_EVENT;
|
||||
Events = 0;
|
||||
Socket = INVALID_SOCKET;
|
||||
|
||||
// INET address family
|
||||
SockAddrIn.sin_family = AF_INET;
|
||||
|
||||
// Any address will do
|
||||
SockAddrIn.sin_addr.s_addr = INADDR_ANY;
|
||||
|
||||
// Convert to network ordering
|
||||
SockAddrIn.sin_port = htons(0);
|
||||
}
|
||||
|
||||
// Default destructor
|
||||
CSocket::~CSocket()
|
||||
{
|
||||
}
|
||||
|
||||
// Return winsock socket handle
|
||||
SOCKET CSocket::GetSocket()
|
||||
{
|
||||
return Socket;
|
||||
}
|
||||
|
||||
// Set winsock socket handle
|
||||
VOID CSocket::SetSocket(SOCKET socket)
|
||||
{
|
||||
Socket = socket;
|
||||
}
|
||||
|
||||
|
||||
// Return socket address
|
||||
SOCKADDR_IN CSocket::GetSockAddrIn()
|
||||
{
|
||||
return SockAddrIn;
|
||||
}
|
||||
|
||||
// Set socket address
|
||||
VOID CSocket::SetSockAddrIn(SOCKADDR_IN sockaddrin)
|
||||
{
|
||||
SockAddrIn = sockaddrin;
|
||||
}
|
||||
|
||||
// Associate winsock events with socket
|
||||
VOID CSocket::SetEvents(LONG lEvents)
|
||||
{
|
||||
if (Event == WSA_INVALID_EVENT) {
|
||||
// Create socket event
|
||||
Event = WSACreateEvent();
|
||||
if (Event == WSA_INVALID_EVENT)
|
||||
throw ESocketOpen(TS("Unable to create event."));
|
||||
}
|
||||
|
||||
if (lEvents != Events) {
|
||||
// Associate network events with socket
|
||||
if (WSAEventSelect(Socket, Event, lEvents) == SOCKET_ERROR)
|
||||
throw ESocketOpen(TS("Unable to select socket events."));
|
||||
Events = lEvents;
|
||||
}
|
||||
}
|
||||
|
||||
// Return associated winsock events
|
||||
LONG CSocket::GetEvents()
|
||||
{
|
||||
return Events;
|
||||
}
|
||||
|
||||
// Open socket
|
||||
VOID CSocket::Open()
|
||||
{
|
||||
}
|
||||
|
||||
// Close socket
|
||||
VOID CSocket::Close()
|
||||
{
|
||||
}
|
||||
|
||||
|
||||
// *********************** CServerClientSocket ***********************
|
||||
|
||||
// Constructor with serversocket as parameter
|
||||
CServerClientSocket::CServerClientSocket(LPCServerSocket lpServerSocket)
|
||||
{
|
||||
ServerSocket = lpServerSocket;
|
||||
}
|
||||
|
||||
// Transmit data to socket
|
||||
INT CServerClientSocket::Transmit( LPCSTR lpsBuffer, UINT nLength)
|
||||
{
|
||||
return send(Socket, lpsBuffer, nLength, 0);
|
||||
}
|
||||
|
||||
// Send a string to socket
|
||||
INT CServerClientSocket::SendText( LPCSTR lpsText)
|
||||
{
|
||||
static CHAR crlf[3] = {0x0D, 0x0A, 0x00};
|
||||
INT nCount;
|
||||
|
||||
nCount = Transmit(lpsText, strlen(lpsText));
|
||||
nCount += Transmit(crlf, strlen(crlf));
|
||||
return nCount;
|
||||
}
|
||||
|
||||
// Receive data from socket
|
||||
INT CServerClientSocket::Receive(LPSTR lpsBuffer, UINT nLength)
|
||||
{
|
||||
return recv(Socket, lpsBuffer, nLength, 0);
|
||||
}
|
||||
|
||||
// Process winsock messages if any
|
||||
VOID CServerClientSocket::MessageLoop()
|
||||
{
|
||||
UINT nStatus;
|
||||
WSANETWORKEVENTS NetworkEvents;
|
||||
|
||||
nStatus = WSAWaitForMultipleEvents(1, &Event, FALSE, 0, FALSE);
|
||||
if ((nStatus == 0) && (WSAEnumNetworkEvents(Socket, Event, &NetworkEvents) != SOCKET_ERROR)) {
|
||||
if ((NetworkEvents.lNetworkEvents & FD_READ) != 0) {
|
||||
OnRead();
|
||||
}
|
||||
if ((NetworkEvents.lNetworkEvents & FD_CLOSE) != 0) {
|
||||
OnClose();
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
// Return server socket that own this socket
|
||||
LPCServerSocket CServerClientSocket::GetServerSocket()
|
||||
{
|
||||
return ServerSocket;
|
||||
}
|
||||
|
||||
|
||||
// *********************** CServerClientThread ***********************
|
||||
|
||||
CServerClientThread::CServerClientThread(LPCServerClientSocket lpSocket)
|
||||
{
|
||||
ClientSocket = lpSocket;
|
||||
}
|
||||
|
||||
CServerClientThread::~CServerClientThread()
|
||||
{
|
||||
ClientSocket->GetServerSocket()->RemoveClient((LPCServerClientThread) this);
|
||||
}
|
||||
|
||||
|
||||
// ************************** CServerSocket **************************
|
||||
|
||||
// Default constructor
|
||||
CServerSocket::CServerSocket()
|
||||
{
|
||||
}
|
||||
|
||||
// Default destructor
|
||||
CServerSocket::~CServerSocket()
|
||||
{
|
||||
if (Active)
|
||||
Close();
|
||||
}
|
||||
|
||||
// Open server socket so clients can connect
|
||||
VOID CServerSocket::Open()
|
||||
{
|
||||
assert(!Active);
|
||||
|
||||
// Convert to network ordering
|
||||
SockAddrIn.sin_port = htons(Port);
|
||||
|
||||
if (Socket == INVALID_SOCKET) {
|
||||
// Create socket
|
||||
Socket = socket(AF_INET, SOCK_STREAM, 0);
|
||||
if (Socket == INVALID_SOCKET)
|
||||
throw ESocketOpen(TS("Unable to allocate a socket."));
|
||||
}
|
||||
|
||||
// Associate an address with server socket
|
||||
if (bind(Socket, (struct sockaddr FAR *) &SockAddrIn, sizeof(SockAddrIn)) == SOCKET_ERROR)
|
||||
throw ESocketOpen(TS("Unable to associate address with socket."));
|
||||
|
||||
// Listen for incoming connections
|
||||
if (listen(Socket, MAX_PENDING_CONNECTS) != 0)
|
||||
throw ESocketOpen(TS("Unable to listen on socket."));
|
||||
|
||||
// Associate network events with socket
|
||||
SetEvents(FD_ACCEPT | FD_CONNECT | FD_CLOSE);
|
||||
|
||||
Active = TRUE;
|
||||
}
|
||||
|
||||
// Close server socket and all current connections
|
||||
VOID CServerSocket::Close()
|
||||
{
|
||||
assert(Active);
|
||||
|
||||
if (Event != WSA_INVALID_EVENT) {
|
||||
// Tell winsock not to notify us about any events
|
||||
if (WSAEventSelect(Socket, Event, 0) == SOCKET_ERROR)
|
||||
throw ESocketClose(TS("Unable to select socket events."));
|
||||
|
||||
if (!WSACloseEvent(Event))
|
||||
throw ESocketClose(TS("Unable to close socket event."));
|
||||
Event = WSA_INVALID_EVENT;
|
||||
}
|
||||
|
||||
CIterator<LPCServerClientThread> *i = Connections.CreateIterator();
|
||||
|
||||
// Terminate and free all client threads
|
||||
for (i->First(); !i->IsDone(); i->Next()) {
|
||||
//i->CurrentItem()->Terminate();
|
||||
delete i->CurrentItem();
|
||||
}
|
||||
delete i;
|
||||
Connections.RemoveAll();
|
||||
|
||||
closesocket(Socket);
|
||||
Socket = INVALID_SOCKET;
|
||||
|
||||
Active = FALSE;
|
||||
}
|
||||
|
||||
// Set port number to listen on
|
||||
VOID CServerSocket::SetPort(UINT nPort)
|
||||
{
|
||||
assert(!Active);
|
||||
|
||||
Port = nPort;
|
||||
}
|
||||
|
||||
// Process messages from winsock if any
|
||||
VOID CServerSocket::MessageLoop()
|
||||
{
|
||||
UINT nStatus;
|
||||
INT nAddrLen;
|
||||
SOCKET ClientSocket;
|
||||
SOCKADDR_IN SockAddrIn;
|
||||
WSANETWORKEVENTS NetworkEvents;
|
||||
LPCServerClientSocket lpClient;
|
||||
LPCServerClientThread lpThread;
|
||||
|
||||
nStatus = WSAWaitForMultipleEvents(1, &Event, FALSE, 0, FALSE);
|
||||
if ((nStatus == 0) && (WSAEnumNetworkEvents(Socket, Event, &NetworkEvents) != SOCKET_ERROR)) {
|
||||
if ((NetworkEvents.lNetworkEvents & FD_ACCEPT) != 0) {
|
||||
lpClient = OnGetSocket(this);
|
||||
nAddrLen = sizeof(SockAddrIn);
|
||||
ClientSocket = accept(Socket, (SOCKADDR *) &SockAddrIn, &nAddrLen);
|
||||
if (ClientSocket != INVALID_SOCKET) {
|
||||
// Set socket handle
|
||||
lpClient->SetSocket(ClientSocket);
|
||||
// Set socket address
|
||||
lpClient->SetSockAddrIn(SockAddrIn);
|
||||
// Set winsock events
|
||||
lpClient->SetEvents(FD_READ | FD_CLOSE);
|
||||
// Create client connection thread
|
||||
lpThread = OnGetThread(lpClient);
|
||||
// Add client thread to connection list
|
||||
InsertClient(lpThread);
|
||||
// Call OnAccept event handler
|
||||
OnAccept(lpThread);
|
||||
} else {
|
||||
delete lpClient;
|
||||
lpClient = NULL;
|
||||
throw ESocketOpen(TS("No more sockets available."));
|
||||
}
|
||||
}
|
||||
/*if ((NetworkEvents.lNetworkEvents & FD_CONNECT) != 0) {
|
||||
}
|
||||
if ((NetworkEvents.lNetworkEvents & FD_CLOSE) != 0) {
|
||||
}*/
|
||||
}
|
||||
}
|
||||
|
||||
// Insert client into connection list
|
||||
VOID CServerSocket::InsertClient(LPCServerClientThread lpClient)
|
||||
{
|
||||
Connections.Insert(lpClient);
|
||||
}
|
||||
|
||||
// Remove client from connection list
|
||||
VOID CServerSocket::RemoveClient(LPCServerClientThread lpClient)
|
||||
{
|
||||
Connections.Remove(lpClient);
|
||||
}
|
||||
|
||||
// OnGetSocket event handler
|
||||
LPCServerClientSocket CServerSocket::OnGetSocket(LPCServerSocket lpServerSocket)
|
||||
{
|
||||
return NULL;
|
||||
}
|
||||
|
||||
// OnGetThread event handler
|
||||
LPCServerClientThread CServerSocket::OnGetThread(LPCServerClientSocket lpSocket)
|
||||
{
|
||||
return NULL;
|
||||
}
|
||||
|
||||
|
||||
// Initialize WinSock DLL
|
||||
VOID InitWinsock()
|
||||
{
|
||||
WORD wVersionRequested;
|
||||
WSADATA wsaData;
|
||||
|
||||
wVersionRequested = MAKEWORD(2, 0);
|
||||
|
||||
if (WSAStartup(wVersionRequested, &wsaData) != 0)
|
||||
// Return FALSE as we couldn't find a usable WinSock DLL
|
||||
throw ESocketWinsock(TS("Unable to initialize winsock dll."));
|
||||
|
||||
/* Confirm that the WinSock DLL supports 2.0 */
|
||||
|
||||
if (LOBYTE(wsaData.wVersion) != 2 || HIBYTE(wsaData.wVersion) != 0) {
|
||||
// We couldn't find a usable winsock dll
|
||||
WSACleanup();
|
||||
throw ESocketDll(TS("Winsock dll version is not 2.0 or higher."));
|
||||
}
|
||||
}
|
||||
|
||||
// Deinitialize WinSock DLL
|
||||
VOID DeinitWinsock()
|
||||
{
|
||||
if (WSACleanup() != 0)
|
||||
throw ESocketWinsock(TS("Unable to deinitialize winsock dll."));
|
||||
}
|
Loading…
Add table
Add a link
Reference in a new issue