С чего можно начать обучение?
Я начал вот с этой книги ib.mexmat.ru/books/24321 но там в примерах есть ошибки. Сейчас пытаюсь сварганить простейшее клиент-серверное приложение с помощью этого примера //forum.codenet.ru/showthread.php?t=18997, но там тоже возникли проблемы при соединении через интернет, а не по локалке.
13 ноября 2009 в 21:00
Нет, не заработало Подключение происходит – и тут же разрывается. В роутере открывал 6666 и 666 порты для TSP, ни через один постоянное соединение не установилось. Пробую подключиться к серверу telnet-ом – глухо, как в танке. Зло***чий Домолинк
13 ноября 2009 в 20:02
всё наладил, дело было в роутере – пробросил нужные порты и заработало
11 ноября 2009 в 19:02
узнай ещё свой ip например набрав в командной строке ipconfig или в свойствах установившегося соединения ethernet там тоже самое?
11 ноября 2009 в 18:02
// Пример простого TCP-сервера
#include <stdio.h>
#include <iostream.h>
#include <winsock2.h>
#pragma comment(lib, "WSock32.lib") // Используем эту библиотеку
#define MY_PORT 666 // Порт, который слушает сервер – 666
// макрос для печати количества активных пользователей
#define PRINTNUSERS if (nclients) printf("%d user on-line\n", nclients); \
else printf("No User on line\n");
// прототип функции, обслуживающий подключившихся пользователей
DWORD WINAPI SexToClient(LPVOID client_socket);
// глобальная переменная – количество активных пользователей
int nclients = 0;
void RussianMessage(char *str);
int main(int argc, char* argv[])
{
char buff[1024]; // Буфер для различных нужд
printf("TCP SERVER DEMO \n");
// Шаг 1 – Инициализация Библиотеки Сокетов
// т.к. возвращенная функцией информация не используется
// ей передается указатель на рабочий буфер, преобразуемый к указателю
// на структуру WSAD?4??4??1?.
// Такой прием позволяет сэкономить одну переменную, однако, буфер
// должен быть не менее полкилобайта размером (структура WSAD?4??4??1?
// занимает 400 байт)
if (WSAStartup(0×0202, (WSAD?4??4??1? *)&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 – ожидание подключений
// размер очереди – 0×100
if (listen(mysocket, 0×100))
{
// Ошибка
printf("Error listen %d\n", WSAGetLastError());
closesocket(mysocket);
WSACleanup();
return -1;
}
RussianMessage("Ожидание подключений…");
// Шаг 5 – извлекаем сообщение из очереди
SOCKET client_socket; // сокет для клиента
sockaddr_in client_addr; // адрес клиента (заполняется системой)
// функции accept необходимо передать размер структуры
int client_addr_size = sizeof(client_addr);
11 ноября 2009 в 18:02
// цикл извлечения запросов на подключение из очереди
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 "Приём!\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){
buff[bytes_recv]=0;
cout << buff; cout << endl;
fgets(&buff[0], sizeof(buff) – 1, stdin);
send(my_sock, &buff[0], bytes_recv, 0);
}
// если мы здесь, то произошел выход из цикла по причине
// возращения функцией recv ошибки – соединение с клиентом разорвано
nclients–; // уменьшаем счетчик активных клиентов
printf("-disconnect\n"); PRINTNUSERS
// закрываем сокет
closesocket(my_sock);
return 0;
}
void RussianMessage(char *str)
{
char message[20 * 1024];
CharToOem(str,message);
cout<<message <<endl;
}
11 ноября 2009 в 18:02
К Интернету подключен через провайдера Домолинк-Воронеж. Свой ip узнавал с помощью 2ip.ru Через прокси не сижу. Хз что делать, в общем.
11 ноября 2009 в 18:01
Собственно, код базируется на статье Криса, ссылкая на которую есть выше
// Пример простого TCP-клиента
#include <stdio.h>
#include <string.h>
#include <iostream.h>
#include <winsock2.h>
#pragma comment(lib, "WSock32.lib") // Используем эту библиотеку
#define PORT 666
#define SERVERADDR "77.45.165.105" // 127.0.0.1
void RussianMessage(char *str);
int main(int argc, char* argv[])
{
char buff[1024];
printf("TCP DEMO CLIENT\n");
// Шаг 1 – инициализация библиотеки Winsock
if (WSAStartup(0×202, (WSAD?4??4??1? *)&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;
}
RussianMessage("Соединение с ");
RussianMessage(SERVERADDR);
RussianMessage(" успешно установлено\n \
Type quit for quit\n\n");
cout << endl;
// Шаг 4 – чтение и передача сообщений
int nsize;
while ((nsize = recv(my_sock, &buff[0], sizeof(buff) – 1, 0)) != SOCKET_ERROR)
{
// ставим завершающий ноль в конце строки
buff[nsize] = 0;
// выводим на экран
RussianMessage("Юстас=>Алексу:");
RussianMessage(buff);
cout << endl;
// читаем пользовательский ввод с клавиатуры
RussianMessage("Алекс=>Юстасу:");
cin >> buff;
// проверка на "quit"
if (!strcmp(&buff[0], "quit\n"))
{
// Корректный выход
printf("Exit…");
closesocket(my_sock);
WSACleanup();
return 0;
}
// передаем строку клиента серверу
send(my_sock, &buff[0], strlen(&buff[0]), 0);
}
printf("Recv error %d\n", WSAGetLastError());
closesocket(my_sock);
WSACleanup();
return -1;
}
void RussianMessage(char *str)
{
char message[256];
CharToOem(str,message);
cout<<message;
}
11 ноября 2009 в 12:05
#5 я тут на кофейной гуще гадаю.. щас… щас.. вижу.. вижу.. ошибка в коде у тебя вот в чём дело.
чего запускаешь на локальный айпишник, на что сам биндишься? как к интернету подключён?
11 ноября 2009 в 11:04
От посмотри, с калбеками, удобно:
//www.alhem.net/Sockets/
C++ Stream Compatible TCP/IP Sockets
//sourceforge.net/projects/cpp-sockets/
//sourceforge.net/projects/fedlibrary/
//netclass.sourceforge.net/
11 ноября 2009 в 10:01
Поищи любу для ++ какую нибудь.
10 ноября 2009 в 22:02
Что-то не срастается – при запуске с локальным ip (127.0.0.1) всё работает нормально. Как только меняю на интернет-ip – соединение не создаётся.
7 ноября 2009 в 22:00
Спасибо большое,очень понятно написано!
7 ноября 2009 в 21:02
//www.citforum.ru/book/cook/winsock.shtml
там разве что про асинхронные сокеты не написано
7 ноября 2009 в 20:05
P.S. С и основы C++ знаю.