Not a member of Pastebin yet?
Sign Up,
it unlocks many cool features!
- #include <WinSock2.h>
- #include <iostream>
- #include <io.h>
- #include <direct.h>
- #define PAUSE system("pause");
- #define MAX_RECV 500
- #define DATA_PORT 20
- #define CONTROL_PORT 21
- #define MAX_CLIENT_COUNT 10
- #define END_M endl; RELEASE_CONSOLE
- #define SYSTEM_M WAIT_CONSOLE cout<<"System : "
- #define SERVER_M WAIT_CONSOLE cout<<"Server -> "
- #define CLIENT_M WAIT_CONSOLE cout<<"Server <- "
- #define RELEASE_COUNTER ReleaseMutex(counterFree);
- #define RELEASE_CONSOLE ReleaseMutex(consoleFree);
- #define WAIT_EMPTY_CLIENT_SLOT WaitForSingleObject(emptyClientSlots,INFINITE);
- #define RELEASE_CLIENT_SLOT ReleaseSemaphore(emptyClientSlots,1,NULL);
- #define WELCOME_WORDS "Welcom to Alex's first FTP server."
- #define WAIT_CONSOLE WaitForSingleObject(consoleFree,INFINITE);
- #define WAIT_COUNTER WaitForSingleObject(counterFree,INFINITE);
- #define PRINT_USERS_COUNT if(CountOfClients) SYSTEM_M<<CountOfClients<<" users on-line"<<END_M else SYSTEM_M<<"No Users on line"<<END_M
- using namespace std;
- DWORD WINAPI workWithClient(LPVOID);
- DWORD WINAPI sendFile(LPVOID);
- int findEmptySlot();
- HANDLE counterFree=CreateMutex(NULL,false,NULL),
- consoleFree=CreateMutex(NULL,false,NULL),
- dataPortFree[MAX_CLIENT_COUNT],
- emptyClientSlots=CreateSemaphore(NULL,MAX_CLIENT_COUNT,MAX_CLIENT_COUNT,NULL);
- int CountOfClients=0;
- WSADATA wsaData;
- SOCKET serverSocket,clientsSockets[MAX_CLIENT_COUNT+1];
- sockaddr_in serverService;
- HANDLE Clients[MAX_CLIENT_COUNT+1];
- int main()
- {
- //--------------------- Инициализация Winsock ---------------------
- int iResult = WSAStartup(WINSOCK_VERSION, &wsaData);
- if (iResult != NO_ERROR)
- {
- SYSTEM_M<<"WSAStartup failed with error: "<<iResult<<END_M PAUSE
- return 1;
- }
- SYSTEM_M<<"WinSock initialized."<<END_M
- //-----------------------------------------------------------------
- //------------------ Создание серверного сокета -------------------
- serverSocket = socket(PF_INET, SOCK_STREAM, IPPROTO_TCP);
- if (serverSocket == INVALID_SOCKET)
- {
- SYSTEM_M<<"Socket failed with error: "<<WSAGetLastError()<<END_M
- WSACleanup(); PAUSE
- return 1;
- }
- SYSTEM_M<<"Socket creation complete."<<END_M
- //-----------------------------------------------------------------
- //--------------------- Установка IP и порта ----------------------
- serverService.sin_family = AF_INET;
- serverService.sin_addr.s_addr = htonl(INADDR_ANY);
- serverService.sin_port = htons(CONTROL_PORT);
- //-----------------------------------------------------------------
- //----------------- Привязка сокета к IP и порту ------------------
- if (bind(serverSocket, (SOCKADDR*) &serverService, sizeof(serverService)) == SOCKET_ERROR)
- {
- SYSTEM_M<<"Binding failed: "<<WSAGetLastError()<<END_M
- if(closesocket(serverSocket)==SOCKET_ERROR)
- {
- SYSTEM_M<<"Error close socket."<<END_M
- WSACleanup(); PAUSE
- return 1;
- }
- WSACleanup(); PAUSE
- return 1;
- }
- SYSTEM_M<<"Binding complete."<<END_M
- //-----------------------------------------------------------------
- //------------------- Начинаем слушать 21 порт --------------------
- if (listen(serverSocket, SOMAXCONN) == SOCKET_ERROR)
- {
- SYSTEM_M<<"Error listening on socket: "<<WSAGetLastError()<<END_M
- if(closesocket(serverSocket)==SOCKET_ERROR)
- {
- SYSTEM_M<<"Error close socket"<<END_M
- WSACleanup(); PAUSE
- return 1;
- }
- WSACleanup();
- system("pause");
- return 1;
- }
- SYSTEM_M<<"Listening on "<<CONTROL_PORT<<" port..."<<END_M
- //-----------------------------------------------------------------
- //----------------- Создание клиентских настроек ------------------
- sockaddr_in clientAddr;
- int clientAddrSize=sizeof(clientAddr);
- //-----------------------------------------------------------------
- //--------------------- Подключение клиентов ----------------------
- SYSTEM_M<<"Waiting for clients to connect..."<<END_M
- for (int i=0, WAIT_EMPTY_CLIENT_SLOT;clientsSockets[i]=accept(serverSocket, (SOCKADDR*) &clientAddr, &clientAddrSize);WAIT_EMPTY_CLIENT_SLOT,i=findEmptySlot())
- {
- if (i!=(-1))
- {
- WAIT_COUNTER CountOfClients++;
- SYSTEM_M<<"Client number "<<CountOfClients<<" connected."<<END_M
- RELEASE_COUNTER
- int* clientPotition=new int;
- *clientPosition=i;
- HOSTENT *hostent;
- hostent=gethostbyaddr((char *) &clientAddr.sin_addr.s_addr, 4, AF_INET);
- SYSTEM_M<<((hostent)?hostent->h_name:"")<<"["<<inet_ntoa(clientAddr.sin_addr)<<"] new connect."<<END_M
- PRINT_USERS_COUNT
- Clients[*clientPosition]=CreateThread(NULL,NULL,workWithClient,(LPVOID)&(*clientPosition),NULL,NULL);
- }
- }
- //-----------------------------------------------------------------
- //------------------ Завершение работы сервера --------------------
- if(closesocket(serverSocket)==SOCKET_ERROR)
- {
- SYSTEM_M<<"Error close socket."<<END_M
- WSACleanup(); PAUSE
- return 1;
- }
- WSACleanup(); PAUSE
- return 0;
- //-----------------------------------------------------------------
- }
- int findEmptySlot()
- {
- bool stop=false;
- for(int i=0;(i<MAX_CLIENT_COUNT+1) && !stop;i++)
- stop=(WaitForSingleObject(slot[i],0)==WAIT_OBJECT_0);
- if (!stop)
- return -1;
- else
- return i-1;
- }
- DWORD WINAPI WorkWithClient(LPVOID position)
- {
- //---------------- Взятие позиции слота клиента -------------------
- int clientPosition=*(int*) position;
- delete(position);
- //-----------------------------------------------------------------
- //------------------- Проверка на переполнение --------------------
- WAIT_COUNTER CountOfClients
- if (CountOfClients<=MAX_CLIENT_COUNT)
- {
- RELEASE_COUNTER
- //------------------ Взятие клиентского сокета --------------------
- SOCKET clientSocket=clientsSockets[clientPosition];
- //-----------------------------------------------------------------
- //------------------------- Приветствие ---------------------------
- send(clientSocket,WELCOME_WORDS,sizeof(WELCOME_WORDS)-1,0);
- //-----------------------------------------------------------------
- }
- CountOfClients--;
- RELEASE_COUNTER
- SYSTEM_M<<"To many clients."<<END_M
- //-----------------------------------------------------------------
- //--------------- Извещение о переполнении клиента ----------------
- if (send(clientSocket,"Sorry, to many clients, try later.",34,0)!=SOCKET_ERROR)
- {
- SYSTEM_M<<"Message sending to client in position "<<clientPosition<<", complete."<<END_M
- return 0;
- } else
- {
- SYSTEM_M<<"Message sending to client in position "<<clientPosition<<", failed."<<END_M
- return 1;
- }
- //-----------------------------------------------------------------
- }
Add Comment
Please, Sign In to add comment