Наши проекты:
Журнал · Discuz!ML · Wiki · DRKB · Помощь проекту |
||
ПРАВИЛА | FAQ | Помощь | Поиск | Участники | Календарь | Избранное | RSS |
[18.97.9.175] |
|
Сообщ.
#1
,
|
|
|
Доброго времени суток!
Поставили мне - НЕпрограммисту от слова совсем - сделать некую утилиту с использованием UDP. (Если это имеет значение, делаю оконное приложение в MFC на VisualStudio2017). Не работает. Сделала пару сервер-клиент. Не хотят разговаривать между собой. Достала из свалки ПО Packet Sender и Wireshark. Отправляю ПакетСендером "Hello, world" по UDP на адрес 127.0.0.1 или на свой IP, а Wireshark вообще не видит от меня вообще никаких пакетов по UDP. Брандмаузер и Касперского уже отключила. Помогите пожалуйста, а то уже скоро начну стучаться бубном об тейбл. const char* SendingremoteIP = "127.0.0.1"; USHORT SendingremotePort = 5000; const char* ClientIP = "127.0.0.1"; USHORT ClientPort = 5050; int handle, new_handle; WSADATA WsaData; void CAutomat::StartSocket() { CString Msg; SOCKADDR_IN sin; sin.sin_family = AF_INET; sin.sin_port = htons(SendingremotePort); sin.sin_addr.s_addr = ::inet_addr(SendingremoteIP); int addrlen = sizeof(sin); int errW = WSAStartup(0x0101, &WsaData); if (errW == SOCKET_ERROR) { Msg.Format("WSAStartup() failed: %ld\n", GetLastError()); AfxMessageBox(Msg); } handle = socket(AF_INET, SOCK_DGRAM, IPPROTO_UDP); if (handle <= 0) { Msg.Format(" failed to create socket\n %d\n", handle); AfxMessageBox(Msg); } else { Msg.Format("socket created\n %d\n", handle); AfxMessageBox(Msg); } int errB = bind(handle, (const sockaddr*)&sin, sizeof(sin)); if (errB < 0) { Msg.Format(" failed to bind\n errB=%d Port=%d\n", errB, sin.sin_port); AfxMessageBox(Msg); } else { Msg.Format("binded\n errB=%d Port=%d\n", errB, sin.sin_port); AfxMessageBox(Msg); } DWORD nonBlocking = 1; if (ioctlsocket(handle, FIONBIO, &nonBlocking) != 0) { Msg.Format(" Невозможно перевести порт в неблокирующий режим"); AfxMessageBox(Msg); } listen(handle, 3); new_handle = accept(handle, (struct sockaddr *)&sin, (socklen_t*)&addrlen); } int CAutomat::Writeing(unsigned long WordNumber) { ///Тест!!! Это надо удалить!!!!! AfxMessageBox(_T("Трансляция команды")); CString Msg; char * SendingData; unsigned long SendingBytes; SOCKADDR_IN client; client.sin_family = AF_INET; client.sin_addr.s_addr = ::inet_addr(ClientIP); client.sin_port = htons(ClientPort); SendingData = "Hello, world!"; SendingBytes = sizeof(SendingData); int sent_bytes = sendto(new_handle, SendingData, SendingBytes, 0, (struct sockaddr *)&client, sizeof(sockaddr_in)) ; if (sent_bytes != SendingBytes) { Msg.Format("Failed to send packet: return value = %d\n", sent_bytes); AfxMessageBox(Msg); } return 0; Reading(); } UINT16 CAutomat:: Reading() { CString Msg; SOCKADDR_IN client; client.sin_family = AF_INET; client.sin_addr.s_addr = ::inet_addr(ClientIP); client.sin_port = htons(ClientPort); unsigned char packet_data[256]; unsigned int maximum_packet_size = sizeof(packet_data); sockaddr_in from; socklen_t fromLength = sizeof(from); for (int i = 0; i < 256; i++) packet_data[i] = 0x00; int received_bytes; received_bytes = recvfrom(new_handle, (char*)packet_data, maximum_packet_size, 0, (sockaddr*)&from, &fromLength); int errR=WSAGetLastError(); if (received_bytes <= 0) { Msg.Format("Failed to get packet: return value = %d errR=%d\n", received_bytes, errR); AfxMessageBox(Msg); } else { Msg.Format("Ой, чёйта? = %d errR=%d\n", received_bytes, errR); AfxMessageBox(Msg); } } |
Сообщ.
#2
,
|
|
|
Adry, код в студию!
|
Сообщ.
#3
,
|
|
|
Цитата JoeUser @ У меня ПакетСендер И Ваершарк друг-друга не видят. Я боюсь, что что система блокирует UDP. А может и не только UDP |
Сообщ.
#4
,
|
|
|
Цитата Adry @ Сделала пару сервер-клиент. Не хотят разговаривать между собой. Для UDP сокетов на сервере listen не нужно делать. Просто делаешь bind, потом в цикле select и recv, насколько я помню. |
Сообщ.
#5
,
|
|
|
Цитата Adry @ У меня ПакетСендер И Ваершарк друг-друга не видят. Я боюсь, что что система блокирует UDP. А может и не только UDP А вот это: handle = socket(AF_INET, SOCK_DGRAM, IPPROTO_UDP); и int sent_bytes = sendto(new_handle, SendingData, SendingBytes, 0, (struct sockaddr *)&client, sizeof(sockaddr_in)) точно правильно ? --- Для клиента UDP общий алгоритм такой: 1. WSAStartup 2. Создаём Socket = ::socket(domain,type,protocol); 3. заполним структуру struct sockaddr_in addr; 4. посредством "select" узнаем, нет ли ошибки и готов ли сокет к передаче 5. Если нет ошибок и готов к передаче -> sendto(Socket,... --- Весьма полезно сделать процедуру, приблизительно такую: int SendTo (const TCHAR* pIp, unsigned short int port, const char *pBuf, size_t sizeBuf, int flags); --- Пару Echo UDP Client и Echo UDP Server я могу дать, только сервер оформлен службой. |
Сообщ.
#6
,
|
|
|
Наверху страницы сетевого программирования есть кнопка Поиск - с лупой...
Вбейте в запрос UDP и получите 6! страниц и все про UDP вплоть и MFC и прочая...и простые коды для клиента сервера. И откуда в UDP такой код??? Цитата listen(handle, 3); new_handle = accept(handle, (struct sockaddr *)&sin, (socklen_t*)&addrlen); Это только для TCP!!! Найдите по поиску код простого приложения для UDP и уж потом заверните его в классы... |
Сообщ.
#7
,
|
|
|
Цитата Oleg2004 @ Наверху страницы сетевого программирования есть кнопка Поиск - с лупой... Вбейте в запрос UDP и получите 6! страниц и все про UDP вплоть и MFC и прочая...и простые коды для клиента сервера. И откуда в UDP такой код??? Цитата listen(handle, 3); new_handle = accept(handle, (struct sockaddr *)&sin, (socklen_t*)&addrlen); Это только для TCP!!! Найдите по поиску код простого приложения для UDP и уж потом заверните его в классы... Да. Я даже отсюда [C++] WinSock (простая библиотека) скачала библиотеку. Неделю ее прикручивала, еще неделю разбиралась. Она у меня не заработала. accept это я уже от безнадеги в пятницу приписала. Как и следовало ожидать, не помогло... |
Сообщ.
#8
,
|
|
|
Цитата ЫукпШ @ Пару Echo UDP Client и Echo UDP Server я могу дать, только сервер оформлен службой. Спасибо, я уже нашла Ваши приложения. Разбираюсь Еще раз хотелось бы подчеркнуть, что Wireshark и Packet Sender - это _НЕ МОИ_ приложения. Это выкачанные из интернета программы. И они у меня на машине (с Win10 и Касперским) друг друга не видят. Может быть Винда как-то блокирует обмен по UDP и молчит? |
Сообщ.
#9
,
|
|
|
Цитата Adry @ Как и следовало ожидать, не помогло... Может быть поможет: |
Сообщ.
#10
,
|
|
|
Цитата Adry @ Может быть Винда как-то блокирует обмен по UDP и молчит? Adry, блокировка сетевой активности конечно может быть. Это либо брандмауэр Касперского, либо самой Виндус. Это надо проверять. Однако, хочу заметить, что DNS-обмен обеспечивается протоколом поверх UDP. А раз "интернет работает" то принципиальных проблем с UDP в компе нет. --- Готовые приложения я предлагал с целью "послать UDP пакет и увидеть его ВиреШарком". |
Сообщ.
#11
,
|
|
|
Сейчас запускала Wireshark , и он у меня спросил: "Какой интерфейс будем слушать Ethernet1 или Ethernet2"
Задумалась. Сетевая карта-то у меня одна. Но разъемов там два. Если, допустим, Packet Sender шлет на Ethernet1, а Wireshark "слушает" Ethernet2.... Это может влиять вообще как-то? |
Сообщ.
#12
,
|
|
|
Цитата Adry @ Сейчас запускала Wireshark , и он у меня спросил: "Какой интерфейс будем слушать Ethernet1 или Ethernet2" Задумалась. Прослушать оба. По очереди. Кроме того - допустим, WireShark не видит UDP пакеты некого приложения. А UDP пакеты DNS от браузера он видит ? Помню, что в похожей ситуации я их наблюдал. |
Сообщ.
#13
,
|
|
|
Ни там, ни там не слышит
Добавлено Цитата ЫукпШ @ Кроме того - допустим, WireShark не видит UDP пакеты некого приложения. А UDP пакеты DNS от браузера он видит ? Помню, что в похожей ситуации я их наблюдал. От совсем других IP адресов идут пакеты TCP иTLSv1.2 (Обмен данными с открытыми вкладками браузера?) По UDP идут пакеты не с моего IP на мультикаст, если я правильно понимаю "114","16:17:05,085559","193.232.11.125","224.2.2.2","UDP","72","64914 → 8995 Len=30" Это, по-моему, адрес принтера какого-то |
Сообщ.
#14
,
|
|
|
Adry
Выложите пожалуйста последний вариант вашего кода - там где нет Listen и Accept Четко обозначьте - здесь клиент, а здесь - сервер. Уберите ioctlsocket() - в простом тестовом варианте он лишний, равно как и select() Логика взаимодействия очень простая. Сделайте все общение одноразовым. Запускаем сервер первым - и он ждет на recvfrom() Потом запускаем клиента и ждем приема на сервере. Сервер должен обязательно выдать сообщение о приеме. |
Сообщ.
#15
,
|
|
|
Oleg2004,ЫукпШ, спасибо большое за помощь!
Клиент смог передать пакет серверу, сервер что-то получил. Проблема, как обычно, оказалась в прокладке между стулом и компьютером. Когда привела в порядок код (стиль "деффочка в истерике" обычно работает плохо) и разобралась с порядком обращений (клиент все же должен отправить запрос первым), процесс пошел. Правда, у меня образовался другой вопрос (может быть, подскажите, куда читать). У меня есть мое приложение - оно же сервер UDP. Клиент будет на другом устройстве (контроллере БигльБон), он может работать, может не работать. Если я завожу свое приложение в режиме сервера, я, получается, завишу от БигльБона: если он не работает, моя программа тоже не работает? |
Сообщ.
#16
,
|
|
|
Цитата Adry @ Клиент будет на другом устройстве (контроллере БигльБон), он может работать, может не работать. Если я завожу свое приложение в режиме сервера, я, получается, завишу от БигльБона: если он не работает, моя программа тоже не работает? Согласно стандартному общению по протоколу UDP, сервер висит на recvfrom() бесконечно - если он запущен один раз и на нем нет никаких таймаутов или каких то других условий - ну, например принял 5 пакетов и все, больше не буду работать - по которым он может прекратить свою работу. Клиент может запуститься, послать одну датаграмму или несколько - и отрубиться полностью - можно и комп вырубить. На сервер на другом устройстве это нисколько не влияет. Они ведь согласно вам находятся на физически разных устройствах... |
Сообщ.
#17
,
Сообщение отклонено: Oleg2004 -
|