Ну вот, еще один примитивный исходник:
Код:
#include <iostream>
#include <process.h>
#include <windows.h>
#include <conio.h>
using namespace std;
#pragma comment (lib, "ws2_32.lib")
#pragma comment (lib, "mswsock.lib")
unsigned int _stdcall client_thread(void *client_soket)
{
char Message[200];
SOCKET Client = (SOCKET)client_soket;
int len = 0;
do {
// Приём сообщения от клиента
len = recv(Client, Message, 200, 0);
// Обработка сообщения
// Если ошибка, выходим из цикла ожидания.
if(len == SOCKET_ERROR) break;
// Если длина сообщения 0, значит клиент закрыл свой сокет.
if(len == 0){
cout << "Client socket closed." << endl;
break;
}
cout << Message << " ";
// Отправка сообщения клиенту (эхо)
len = send(Client, Message, strlen(Message) + 1, 0);
// Если ошибка, выходим из цикла ожидания.
if(len == SOCKET_ERROR) break;
cout << " (echo sent)" << endl;
} while (1);
closesocket(Client);
_endthreadex(0);
return 0;
}
void main(void) {
char hname [64]; // Имя хоста
WSAData WSADat; // Свойства WinSock (результат функции WSAStartup)
sockaddr_in server_sin; // Свойства(адрес) создаваемого сокета сервера
sockaddr_in client_sin; // Свойства(адрес) создаваемого сокета сервера
SOCKET Client, Sock; // Серверный и клиентский сокеты
WORD wVersionRequested; // Версия WinSock
int res;
HANDLE hThread;
// Инициализация WinSock 0x0202. Может быть 1.0, 1.1, 2.0, 2.2
wVersionRequested = MAKEWORD( 2, 2 );
// WSADat - структура, куда будут занесены результаты инициализации
if(WSAStartup(wVersionRequested, &WSADat))
{cout << "Winsock can't be initialized. Press any key to exit..."; _getch(); return;}
// Получение имени текущего ПК
if(gethostname(hname, 64) == SOCKET_ERROR)
{cout << "Not host name. Press any key to exit..."; _getch(); return;}
memset (&server_sin, 0, sizeof(server_sin));
server_sin.sin_family = AF_INET; // Тип адреса
server_sin.sin_addr.s_addr = htonl(INADDR_ANY); // IP-адрес сервера, здесь 0, можно так: inet_addr("127.0.0.1")
server_sin.sin_port = htons(2803); // Номер порта сервера
// Создание сокета
Sock = socket(AF_INET, SOCK_STREAM, IPPROTO_TCP);
if (Sock == INVALID_SOCKET)
{cout << "Error create socket. Press any key to exit..."; _getch(); return;}
// Связывание созданного сокета с адресом sin
res = bind(Sock, (sockaddr*)&server_sin, sizeof(server_sin));
if (res == SOCKET_ERROR)
{cout << "Error bind socket. Press any key to exit..."; _getch(); return;}
// Прослушивание сокета сервером (для подключения клиента)
res = listen(Sock, SOMAXCONN);
if(res == SOCKET_ERROR)
{cout << "Error listen socket. Press any key to exit..."; _getch(); return;}
// Ожидание клиента
hThread = NULL;
while(1)
{
cout << "Wait of client..." << endl;
// Стартуем поток обработки клента, если таковой был создан после accept
if(hThread)
{
ResumeThread(hThread);
CloseHandle(hThread);
hThread = NULL;
}
// Если дождались очередного клиента, делаем аccept
int sin_len = sizeof(client_sin);
memset (&server_sin, 0, sin_len);
Client = accept(Sock, (sockaddr*)&client_sin, &sin_len);
if(Client == INVALID_SOCKET)
{cout << "Error accept client. Press any key to exit..."; _getch(); break;}
// Пытаемся получить имя хоста клиента, его ip и порт
HOSTENT *hst;
hst = gethostbyaddr((char *)&client_sin. sin_addr.s_addr, 4, AF_INET);
char port[6] = "";
_itoa_s(client_sin.sin_port,port,6,10);
// Вывод сведений о клиенте
printf("New client %s [%s:%s] has connected!\n", (hst) ? hst->h_name : "", inet_ntoa(client_sin.sin_addr),port);
// Отправка имени этого компьютера (сервера)
res = send(Client, hname, strlen(hname)+1, 0);
if(res == SOCKET_ERROR)
{cout << "Error send. Press any key to exit..."; _getch(); break;}
cout << " Start client thread...";
// Создаем поток обработки сообщений клиента, стартуем его чуть позже в случае успеха
hThread = (HANDLE)_beginthreadex(NULL, 0, client_thread, (void*)Client, CREATE_SUSPENDED, NULL);
if(!hThread)
{cout << "Error start client thread. Press any key to exit..."; _getch(); break;}
cout << " ok." << endl;
}
CloseHandle(hThread);
closesocket(Sock);
WSACleanup();
}
Идея, как видите в том, что "многопользовательский сервер" обрабатывает каждый коннект в отдельном потоке.
Вообще, есть еще такое интересное понятие, как пул потоков, рекомендую ознакомиться.
Цитата:
Каким образом принятые данные из сокет сервера можно преобразовать в переменные и чтобы во флеше все выстроилось как надо
|
А вот это уже зависит только от того, как вы сами захотите передавать данные: это может быть строка с разделителями, xml или просто любая последовательность байтов.
Цитата:
каким эт образом можно различить юзеров, да даже бонально крестики нолики как свф поймет когда ходит юзер1 а когда юзер2
|
ну, видимо, принимаемые данные должны содержать не только информацию о ходе игры, но и идентификатор пользователя этот ход совершившего.
UPD:
немного причесал исходник.
это читать для дальнейшего понимания, что есть
непримитивный исходник.