Форум программистов
 

Восстановите пароль или Зарегистрируйтесь на форуме, о проблемах и с заказом рекламы пишите сюда - alarforum@yandex.ru, проверяйте папку спам!

Вернуться   Форум программистов > C/C++ программирование > C/C++ Сетевое программирование
Регистрация

Восстановить пароль
Повторная активизация e-mail

Купить рекламу на форуме - 42 тыс руб за месяц

Ответ
 
Опции темы Поиск в этой теме
Старый 20.04.2011, 04:32   #1
Wanstr
Новичок
Джуниор
 
Регистрация: 20.04.2011
Сообщений: 2
По умолчанию Сокеты

Здравствуйте. Взял готовый пример реализации клиент-сервер. Сервер фиксирует подключенных клиентов. Принимает и отправляет то же сообщение тому же клиенту.

Каким образом можно заставить сервер различать клиентов, и реализовать передачу сообщений между ними.
Для начала интересует хотя бы, чтобы сервер передавал полученное сообщение всем клиентам.
Цитата:
send(my_sock,&buff[0],bytes_recv,0);
Я думаю посредством флагов это все реализуется. Но в msdn не смог понять как.

Код:
// Пример простого TCPэхосервера
#include <locale.h>
#include <stdio.h>
#include <winsock2.h> // Wincosk2.h должен быть раньше windows!
#pragma comment(lib, "Ws2_32.lib")


#define MY_PORT 666 // Порт, который слушает сервер
// макрос для печати количества активных пользователей
#define PRINTNUSERS if (nclients) printf("%d user online\n",nclients);else printf("No User on line\n");
// прототип функции, обслуживающий подключившихся пользователей
DWORD WINAPI SexToClient(LPVOID client_socket);
// глобальная переменная – количество активных пользователей
int nclients = 0;
int main(int argc, char* argv[])
{
char buff[1024]; // Буфер для различных нужд
printf("TCP SERVER DEMO\n");
// Шаг 1  Инициализация Библиотеки Сокетов
// Т. к. возвращенная функцией информация не используется
// ей передается указатель на рабочий буфер, преобразуемый к указателю
// на структуру WSADATA.
// Такой прием позволяет сэкономить одну переменную, однако, буфер
// должен быть не менее полкилобайта размером (структура WSADATA
// занимает 400 байт)

if (WSAStartup(0x0202,(WSADATA *) &buff[0]))
{
// Ошибка!
printf("Error WSAStartup %d\n",WSAGetLastError());
return 1;
}
// Шаг 2 создание сокета
SOCKET mysocket;
// AF_INET  сокет Интернета
// SOCK_STREAM  потоковый сокет (с установкой соединения)
// 0  по умолчанию выбирается TCP протокол
if ((mysocket=socket(AF_INET,SOCK_STREAM,0))<0)
{
// Ошибка!
printf("Error socket %d\n",WSAGetLastError());
WSACleanup(); // Деиницилизация библиотеки Winsock
return 1;
}
// Шаг 3 связывание сокета с локальным адресом
sockaddr_in local_addr;
local_addr.sin_family=AF_INET;
local_addr.sin_port=htons(MY_PORT); // не забываем о сетевом порядке!!!
local_addr.sin_addr.s_addr=0; // сервер принимаем подключения
// на все свои IP адреса
// вызываем bind для связывания
if (bind(mysocket,(sockaddr *) &local_addr, sizeof(local_addr)))
{
// Ошибка
printf("Error bind %d\n",WSAGetLastError());
closesocket(mysocket); // закрываем сокет!
WSACleanup();
return 1;
}
// Шаг 4 ожидание подключений
// размер очереди – 0x100
if (listen(mysocket, 0x100))
{
// Ошибка
printf("Error listen %d\n",WSAGetLastError());
closesocket(mysocket);
WSACleanup();
return 1;
}
printf("Ожидание подключений…\n", 
	   setlocale(LC_ALL,"Russian"));
// Шаг 5 извлекаем сообщение из очереди
SOCKET client_socket; // сокет для клиента
sockaddr_in client_addr; // адрес клиента (заполняется системой)

// функции accept необходимо передать размер структуры
int client_addr_size=sizeof(client_addr);
// цикл извлечения запросов на подключение из очереди
while((client_socket=accept(mysocket, (sockaddr *) &client_addr, &client_addr_size)))
{
nclients++; // увеличиваем счетчик подключившихся клиентов
// пытаемся получить имя хоста
HOSTENT *hst;
hst=gethostbyaddr((char *) &client_addr.sin_addr.s_addr,4,AF_INET);
// вывод сведений о клиенте

printf("+%s [%s] new connect!\n",(hst)?hst->h_name:"",inet_ntoa(client_addr.sin_addr));
PRINTNUSERS
// Вызов нового потока для обслужвания клиента
// Да, для этого рекомендуется использовать _beginthreadex
// но, поскольку никаких вызов функций стандартной Си библиотеки
// поток не делает, можно обойтись и CreateThread
DWORD thID;
CreateThread(NULL,NULL,SexToClient,&client_socket,NULL,&thID);
}
return 0;
}
// Эта функция создается в отдельном потоке
// и обсуживает очередного подключившегося клиента независимо от остальных
DWORD WINAPI SexToClient(LPVOID client_socket)
{
SOCKET my_sock;
my_sock=((SOCKET *) client_socket)[0];
char buff[20*1024];
#define sHELLO "Hello, Sailor\r\n"
// отправляем клиенту приветствие
send(my_sock,sHELLO,sizeof(sHELLO),0);
// цикл эхо сервера: прием строки от клиента и возвращение ее клиенту
int bytes_recv;
while( (bytes_recv = recv(my_sock,&buff[0],sizeof(buff),0)) && bytes_recv !=SOCKET_ERROR)
send(my_sock,&buff[0],bytes_recv,0);
// если мы здесь, то произошел выход из цикла по причине
// возращения функцией recv ошибки – соединение с клиентом разорвано
nclients--; // уменьшаем счетчик активных клиентов
printf("disconnect\n"); PRINTNUSERS
// закрываем сокет
closesocket(my_sock);
return 0;
}
Wanstr вне форума Ответить с цитированием
Старый 20.04.2011, 04:33   #2
Wanstr
Новичок
Джуниор
 
Регистрация: 20.04.2011
Сообщений: 2
По умолчанию

Код:
// Пример простого TCPклиента
#include <locale.h>
#include <stdio.h>
#include <string.h>
#include <winsock2.h>
#pragma comment(lib, "Ws2_32.lib")



#define PORT 666
#define SERVERADDR "127.0.0.1"
int main(int argc, char* argv[])
{
char buff[1024];
printf("TCP DEMO CLIENT\n");
// Шаг 1  инициализация библиотеки Winsock
if (WSAStartup(0x202,(WSADATA *)&buff[0]))
{
printf("WSAStart error %d\n",WSAGetLastError());
return 1;
}
// Шаг 2  создание сокета
SOCKET my_sock;
my_sock=socket(AF_INET,SOCK_STREAM,0);
if (my_sock<0)
{
printf("Socket() error %d\n",WSAGetLastError());
return 1;
}
// Шаг 3  установка соединения
// заполнение структуры sockaddr_in – указание адреса и порта сервера
sockaddr_in dest_addr;
dest_addr.sin_family=AF_INET;
dest_addr.sin_port=htons(PORT);
HOSTENT *hst;
// преобразование IP адреса из символьного в сетевой формат
if (inet_addr(SERVERADDR)!=INADDR_NONE)
dest_addr.sin_addr.s_addr=inet_addr(SERVERADDR);
else
// попытка получить IP адрес по доменному имени сервера
if (hst=gethostbyname(SERVERADDR))
// hst->h_addr_list содержит не массив адресов,
// а массив указателей на адреса
((unsigned long *)&dest_addr.sin_addr)[0]=((unsigned long **)hst->h_addr_list)[0][0];
else
{
printf("Invalid address %s\n",SERVERADDR);
closesocket(my_sock);
WSACleanup();
return 1;
}

// адрес сервера получен – пытаемся установить соединение
if (connect(my_sock,(sockaddr *)&dest_addr,sizeof(dest_addr)))
{
printf("Connect error %d\n",WSAGetLastError());
return 1;
}
printf("Соединение с %s успешно установлено\n\
Type quit for quit\n\n",setlocale(LC_ALL,"Russian"),SERVERADDR);
// Шаг 4  чтение и передача сообщений
int nsize;
while((nsize=recv(my_sock,&buff[0],sizeof(buff),0))!=SOCKET_ERROR)
{
// ставим завершающий ноль в конце строки
buff[nsize]=0;
// выводим на экран
printf("S=>C:%s",buff);
// читаем пользовательский ввод с клавиатуры
printf("S<=C:"); 
fgets(&buff[0],sizeof(buff),stdin);
// проверка на "quit"
if (!strcmp(&buff[0],"quit\n"))
{
// Корректный выход
printf("Exit...");
closesocket(my_sock);
WSACleanup();
return 0;
}
// передаем строку клиента серверу
send(my_sock,&buff[0],nsize,0);
}
printf("Recv error %d\n",WSAGetLastError());
closesocket(my_sock);
WSACleanup();
return 1;
}
Wanstr вне форума Ответить с цитированием
Старый 13.02.2012, 12:10   #3
Maxislav
 
Регистрация: 13.02.2012
Сообщений: 7
По умолчанию

Единственный пример ТСР для висуал С++.

Меня правда больше интересует куда этот код вставить чтобы в MFC оформить красиво, а не на черный экран выводить.
Maxislav вне форума Ответить с цитированием
Старый 08.04.2012, 17:42   #4
Niyaz.cpp
Пользователь
 
Регистрация: 08.04.2012
Сообщений: 25
По умолчанию

Цитата:
Сообщение от Maxislav Посмотреть сообщение
Единственный пример ТСР для висуал С++.

Меня правда больше интересует куда этот код вставить чтобы в MFC оформить красиво, а не на черный экран выводить.
посмотри вот тут:
http://netcode.ru/cpp/?lang=&katID=6...=69&artID=2797
http://netcode.ru/cpp/?lang=&katID=6...=69&artID=2798

там как раз реализовано в виде диалога
Niyaz.cpp вне форума Ответить с цитированием
Ответ


Купить рекламу на форуме - 42 тыс руб за месяц



Похожие темы
Тема Автор Раздел Ответов Последнее сообщение
Сокеты в C++ MiRiN Общие вопросы C/C++ 5 06.05.2010 16:53
C#, сокеты Namolem Помощь студентам 0 06.05.2010 10:53
Сокеты Raz0r Помощь студентам 2 29.04.2009 14:47
сокеты cross Работа с сетью в Delphi 2 21.12.2006 18:12