sockaddr_in sa;
int namelen = sizeof(sa);
if (::getpeername (socket.GetHandle(), (SOCKADDR*)&sa, &namelen) != 0)
throw exception ("Can't define client's ip address");
// Теперь в sa.sin_addr.s_addr лежит ip-адрес клиента (4-байтное значение).
// Конвертировать в строку можно с помощью inet_ntoa.
Клиент-сервер. помогите доделать.(C++)
пожалуйста помогите с их написанием.
Код:
cheburator, фенкс.
за 2часа мучений разобрался как работает inet_ntoa, откомпилировал. все гут. теперь как бы в файле лучшим образом найти э тот айпи и прочитть ключ к нему....вотъ в чем вопрос.
Вот еще отрывок из того же проекта :) Там задача примерно такая же, только вместо ключа - условный номер клиентской машины.
Идея в том, чтобы файл с соответствиями IP->ключ загрузить сразу при старте программы и сохранить в std::map, а затем искать по IP нужный ключ (в моем случае - номер компьютера) в этом std::map.
Код:
// ЗАГРУЗИМ СООТВЕТСТВИЯ IP-АДРЕСОВ КЛИЕНТОВ И НОМЕРОВ КОМПЬЮТЕРОВ
{
ifstream file ("ip_num.ini");
string str;
while (!file.eof())
{
file >> str;
// Найдем знак =
size_t offset = str.find ('=');
if (offset == string::npos)
throw exception ("Wrong config.ini format");
ULONG ip = inet_addr (str.substr (0, offset).c_str());
DWORD comp = (DWORD) atoi (str.substr (offset+1).c_str());
ip_comp_map.insert (pair<ULONG,DWORD>(ip, comp));
};
}
...
...
// Определить номер компутера.
sockaddr_in sa;
int namelen = sizeof(sa);
if (::getpeername (socket.GetHandle(), (SOCKADDR*)&sa, &namelen) != 0)
throw exception ("Can't define client's ip address");
TerminalServer::ip_comp_map_type::const_iterator iter = TerminalServer::get()->GetIpCompMap().find (sa.sin_addr.s_addr);
TerminalServer::ip_comp_map_type::const_iterator end_iter = TerminalServer::get()->GetIpCompMap().end();
if (iter == end_iter)
throw exception ("Client's computer number is not present in ip_num.ini");
DWORD compnum = iter->second;
// Теперь в compnum лежит номер клиентского компьютера
{
ifstream file ("ip_num.ini");
string str;
while (!file.eof())
{
file >> str;
// Найдем знак =
size_t offset = str.find ('=');
if (offset == string::npos)
throw exception ("Wrong config.ini format");
ULONG ip = inet_addr (str.substr (0, offset).c_str());
DWORD comp = (DWORD) atoi (str.substr (offset+1).c_str());
ip_comp_map.insert (pair<ULONG,DWORD>(ip, comp));
};
}
...
...
// Определить номер компутера.
sockaddr_in sa;
int namelen = sizeof(sa);
if (::getpeername (socket.GetHandle(), (SOCKADDR*)&sa, &namelen) != 0)
throw exception ("Can't define client's ip address");
TerminalServer::ip_comp_map_type::const_iterator iter = TerminalServer::get()->GetIpCompMap().find (sa.sin_addr.s_addr);
TerminalServer::ip_comp_map_type::const_iterator end_iter = TerminalServer::get()->GetIpCompMap().end();
if (iter == end_iter)
throw exception ("Client's computer number is not present in ip_num.ini");
DWORD compnum = iter->second;
// Теперь в compnum лежит номер клиентского компьютера
Формат файла ip_num.ini. Каждый элемент соответствия IP->номер компьютера представлен отдельной строкой. Формат строки - XXX.XXX.XXX.XXX=NNN, где иксы - IP-адрес, NNN - номер компьютера.
переменная ip_comp_map типа TerminalServer::ip_comp_map_type.
TerminalServer::ip_comp_map_type - это typedef std::map<ULONG, DWORD>.
IP_ПРОБЕЛ_КЛЮЧ ?
cheburator, еще раз пасибо.
подключил <fstream>, что есчо надо?
мой
Код:
#include <winsock.h>
#include <conio.h>
#include <fstream>
#include <stdio.h>
#include <map>
#include <string>
using namespace std;
#pragma comment (lib, "ws2_32.lib")
#pragma comment (lib, "mswsock.lib")
#pragma comment(lib,"wsock32.lib")
void main()
{
char PCName [30], ClientName[30];
typedef map<ULONG, DWORD> ip_comp_map_type;
ip_comp_map_type ip_comp_map;
WSAData WSADat; // Свойства WinSock (результат функции WSAStartup)
sockaddr_in sin; // Свойства(адрес) создаваемого сокета
sockaddr_in sa;
SOCKET Sock, Client; // Серверный и клиентский сокеты
// ЗАГРУЗИМ СООТВЕТСТВИЯ IP-АДРЕСОВ КЛИЕНТОВ И НОМЕРОВ КОМПЬЮТЕРОВ
ifstream file ("ip_num.txt");
string str;
while (!file.eof())
{
file >> str;
// Найдем знак =
size_t offset = str.find ('=');
if (offset == string::npos)
throw exception ("Wrong config.ini format");
ULONG ip = inet_addr (str.substr (0, offset).c_str());
DWORD comp = (DWORD) atoi (str.substr (offset+1).c_str());
ip_comp_map.insert (pair<ULONG,DWORD>(ip, comp));
};
WSAStartup(0x0202,&WSADat); // Инициализация WinSock
// 0x0202 - версия WinSock. Может быть 1.0, 1.1, 2.0, 2.2
// WSADat - структура, куда будут занесены рез. инициализации
gethostname(PCName, 30); // Получение имени текущего ПК
sin.sin_family = AF_INET; // Тип адреса
sin.sin_addr.s_addr = 0; // IP-адрес сервера (пори создании сервера можно 0)
sa.sin_addr.s_addr = 0;
sin.sin_port = htons(2803); // Номер порта сервера
Sock = socket(AF_INET, SOCK_STREAM, IPPROTO_TCP); // Создание сокета
bind(Sock, (sockaddr*)&sin, sizeof(sin)); // Связывание созданного сокета с адресом sin
// ***** Ожиданеи клиента
cout << "Wait of client..." << endl;
listen(Sock, SOMAXCONN); // Прослушивание сокета сервером (для подключения клиента)
Client = accept(Sock, (sockaddr*)&sin, 0); // Ожидание клиента
recv(Client, ClientName, 30, 0); // Получение имени компьютера клиента
send(Client, PCName, strlen(PCName) + 1, 0); // Отправка имени этого компьютера (сервера)
int namelen = sizeof(sa);
if (::getpeername (Client, (SOCKADDR*)&sa, &namelen) != 0)
throw exception ("Can't define client's ip address");
cout << "Client ( " << ClientName << " ) has connected!" << endl;
cout << inet_ntoa(sa.sin_addr) << endl;
// Определить номер компутера.
ip_comp_map_type::const_iterator iter = ip_comp_map.find (sa.sin_addr.s_addr);
ip_comp_map_type::const_iterator end_iter = ip_comp_map.end();
if (iter == end_iter)
throw exception ("Client's computer number is not present in ip_num.txt");
DWORD compnum = iter->second;
// Теперь в compnum лежит номер клиентского компьютера
getch();
closesocket(Sock);
closesocket(Client);
WSACleanup();
}
#include <conio.h>
#include <fstream>
#include <stdio.h>
#include <map>
#include <string>
using namespace std;
#pragma comment (lib, "ws2_32.lib")
#pragma comment (lib, "mswsock.lib")
#pragma comment(lib,"wsock32.lib")
void main()
{
char PCName [30], ClientName[30];
typedef map<ULONG, DWORD> ip_comp_map_type;
ip_comp_map_type ip_comp_map;
WSAData WSADat; // Свойства WinSock (результат функции WSAStartup)
sockaddr_in sin; // Свойства(адрес) создаваемого сокета
sockaddr_in sa;
SOCKET Sock, Client; // Серверный и клиентский сокеты
// ЗАГРУЗИМ СООТВЕТСТВИЯ IP-АДРЕСОВ КЛИЕНТОВ И НОМЕРОВ КОМПЬЮТЕРОВ
ifstream file ("ip_num.txt");
string str;
while (!file.eof())
{
file >> str;
// Найдем знак =
size_t offset = str.find ('=');
if (offset == string::npos)
throw exception ("Wrong config.ini format");
ULONG ip = inet_addr (str.substr (0, offset).c_str());
DWORD comp = (DWORD) atoi (str.substr (offset+1).c_str());
ip_comp_map.insert (pair<ULONG,DWORD>(ip, comp));
};
WSAStartup(0x0202,&WSADat); // Инициализация WinSock
// 0x0202 - версия WinSock. Может быть 1.0, 1.1, 2.0, 2.2
// WSADat - структура, куда будут занесены рез. инициализации
gethostname(PCName, 30); // Получение имени текущего ПК
sin.sin_family = AF_INET; // Тип адреса
sin.sin_addr.s_addr = 0; // IP-адрес сервера (пори создании сервера можно 0)
sa.sin_addr.s_addr = 0;
sin.sin_port = htons(2803); // Номер порта сервера
Sock = socket(AF_INET, SOCK_STREAM, IPPROTO_TCP); // Создание сокета
bind(Sock, (sockaddr*)&sin, sizeof(sin)); // Связывание созданного сокета с адресом sin
// ***** Ожиданеи клиента
cout << "Wait of client..." << endl;
listen(Sock, SOMAXCONN); // Прослушивание сокета сервером (для подключения клиента)
Client = accept(Sock, (sockaddr*)&sin, 0); // Ожидание клиента
recv(Client, ClientName, 30, 0); // Получение имени компьютера клиента
send(Client, PCName, strlen(PCName) + 1, 0); // Отправка имени этого компьютера (сервера)
int namelen = sizeof(sa);
if (::getpeername (Client, (SOCKADDR*)&sa, &namelen) != 0)
throw exception ("Can't define client's ip address");
cout << "Client ( " << ClientName << " ) has connected!" << endl;
cout << inet_ntoa(sa.sin_addr) << endl;
// Определить номер компутера.
ip_comp_map_type::const_iterator iter = ip_comp_map.find (sa.sin_addr.s_addr);
ip_comp_map_type::const_iterator end_iter = ip_comp_map.end();
if (iter == end_iter)
throw exception ("Client's computer number is not present in ip_num.txt");
DWORD compnum = iter->second;
// Теперь в compnum лежит номер клиентского компьютера
getch();
closesocket(Sock);
closesocket(Client);
WSACleanup();
}
Чтение строки из файла
1. Подключи #include <map> и <string>
2.
Код:
// Используем пространство имен std
using namespace std;
void main ()
{
// Нужно объявить соответствие ip<->номер
typedef map<ULONG, DWORD> ip_comp_map_type;
ip_comp_map_type ip_comp_map;
using namespace std;
void main ()
{
// Нужно объявить соответствие ip<->номер
typedef map<ULONG, DWORD> ip_comp_map_type;
ip_comp_map_type ip_comp_map;
3. Меняем определение номера компутера
Код:
// Определить номер компутера.
ip_comp_map_type::const_iterator iter = ip_comp_map.find (sa.sin_addr.s_addr);
ip_comp_map_type::const_iterator end_iter = ip_comp_map.end();
if (iter == end_iter)
throw exception ("Client's computer number is not present in ip_num.txt");
DWORD compnum = iter->second;
ip_comp_map_type::const_iterator iter = ip_comp_map.find (sa.sin_addr.s_addr);
ip_comp_map_type::const_iterator end_iter = ip_comp_map.end();
if (iter == end_iter)
throw exception ("Client's computer number is not present in ip_num.txt");
DWORD compnum = iter->second;
Если будут вылезать ошибки компиляции, пиши конкретно текст ошибок.
LINK : warning LNK4075: ignoring '/EDITANDCONTINUE' due to '/INCREMENTAL:NO' specification
LINK : fatal error LNK1201: error writing to program database 'd:\Documents and Settings\boss.1D4A8EB762AB40D\Рабочий стол\Socket\SocketServer\Debug\SocketServer.pdb'; check for insufficient disk space, invalid path, or insufficient privilege
код потправил.
Второе - либо не хватает места на диске, либо попробуй сделать полный ребилд.
First-chance exception at 0x7c81eb33 in soket2.exe: Microsoft C++ exception: exception @ 0x0012f9c8.
Unhandled exception at 0x7c81eb33 in soket2.exe: Microsoft C++ exception: exception @ 0x0012f9c8.
The program '[3276] soket2.exe: Native' has exited with code 0 (0x0).
Думаю надо специалисту запустить соствено и лично посмотреть...
При создании нового проекта проскакивала ошибка-не ожиданный конец файла....., но потом и она исчезла. из этого тупика сам не выбирусь, help...
d:\documents and settings\boss.1d4a8eb762ab40d\мои документы\visual studio projects\soket2\soket2.cpp(60) : warning C4267: 'argument' : conversion from 'size_t' to 'int', possible loss of data
которая ссылается сюда:
Код:
send(Client, PCName, strlen(PCName) + 1, 0); // Отправка имени этого компьютера (сервера)
Лежит во вложении.
с посылкой ключа серверу справлюсь, а с записью ответа клиента\времени\йпи в файл лог.тхт не уверен, как бы мне есчо это организовать? какие функции потребуюся?
Вот пример, где выводится IP и текущее время.
Код:
ofstream log ("log.txt");
time_t current_time;
time (¤t_time);
log << "Client IP " << inet_ntoa (sa.sin_addr) << ", " << ctime (¤t_time);
time_t current_time;
time (¤t_time);
log << "Client IP " << inet_ntoa (sa.sin_addr) << ", " << ctime (¤t_time);
Нужно подключить <time.h>.
Время выводится в UTC (т. е. по гринвичу) в виде "Wed Jan 02 02:03:55 1980\n\0".
Если нужен другой формат, используй функцию localtime, она вернет структуру, содержащую год, месяц, день и т. п.
нюансик только один получился, лог файл каждый запуск сервера заново создается и в итоге там всегда одна запись, хотелось бы знать как сделать чтобы каждый раз строка записывалась.
Цитата: getch()
лог файл каждый запуск сервера заново создается и в итоге там всегда одна запись, хотелось бы знать как сделать чтобы каждый раз строка записывалась.
Вместо
Код:
ofstream log ("log.txt");
попробуем написать
Код:
ofstream log ("log.txt", ios_base::out | ios_base::app);
Тогда файл будет открываться в режиме добавления (т. е. в момент открытия файла существующее содержимое не затрется, а операции записи по умолчанию будут дописывать в конец).
пасибо за подсказку cheburator, все отлично работает.
а это написано под winodws?
Цитата: iCrash
а это написано под winodws?
Ну судя по этим сторочкам
Цитата:
#include <winsock.h>
и
WSAData WSADat;
WSAStartup(0x0202,&WSADat);
Видимо под Windows
А что?)
просто мне нужно все тоже самое, но токо под linux :)