Студопедия

КАТЕГОРИИ:

АвтоАвтоматизацияАрхитектураАстрономияАудитБиологияБухгалтерияВоенное делоГенетикаГеографияГеологияГосударствоДомЖурналистика и СМИИзобретательствоИностранные языкиИнформатикаИскусствоИсторияКомпьютерыКулинарияКультураЛексикологияЛитератураЛогикаМаркетингМатематикаМашиностроениеМедицинаМенеджментМеталлы и СваркаМеханикаМузыкаНаселениеОбразованиеОхрана безопасности жизниОхрана ТрудаПедагогикаПолитикаПравоПриборостроениеПрограммированиеПроизводствоПромышленностьПсихологияРадиоРегилияСвязьСоциологияСпортСтандартизацияСтроительствоТехнологииТорговляТуризмФизикаФизиологияФилософияФинансыХимияХозяйствоЦеннообразованиеЧерчениеЭкологияЭконометрикаЭкономикаЭлектроникаЮриспунденкция

Передача данных через сокет.




// функция реакции на возможность передачи

void CProtocol::OnSend(int ErrCode)

{

CAsyncSocket::OnSend(ErrCode);

m_SendDataSize = 0;

while (m_SendDataSize < m_SendMemory.GetSize()) // пока есть данные для отправки

{

       int n = Send(((BYTE*)m_SendMemory.GetAddr() + m_SendDataSize), m_SendMemory.GetSize()-m_SendDataSize); // запись в буфер сетевухи

       // Анализ ошибок

       if (n == SOCKET_ERROR)

       {

             ErrCode = GetLastError();

             if (ErrCode != WSAEWOULDBLOCK)

             {

                   CString s;

                   s.Format("Ошибка при передаче! Код ошибки %u", ErrCode);

                   MessageBox(0,s,"Сообщение",MB_OK);

                   Close();

             }

       }

       else m_SendDataSize+= n;

}

m_SendMemory.Alloc(0);

m_SendDataSize = 0;

}

 

// функция посылки данных

void CProtocol::SendPacket(const void* p, DWORD size)

{

m_SendMemory.AddToMemory(&size, sizeof(DWORD)); // добавление размера данных

m_SendMemory.AddToMemory((BYTE*)p, size);       // и свмих данных

OnSend(0);

}

Приём данных через сокет.

// получение данных

void CProtocol::OnReceive(int ErrCode)

{

CAsyncSocket::OnReceive(ErrCode);

if (m_IsReceiveSize) // Прием размера данных

{

       int n = Receive((BYTE*)&m_ReceiveSize+m_ReceiveDataSize, sizeof(DWORD)-m_ReceiveDataSize);

       // Анализ ошибок

       if (n == SOCKET_ERROR)

       {

             ErrCode = GetLastError();

             if (ErrCode != WSAEWOULDBLOCK)

             {

                   CString s;

                   s.Format("Ошибка при приеме длины! Код ошибки %u", ErrCode);

                   MessageBox(0,s,"Сообщение",MB_OK);

                   Close();

             }

       }    

       else

       // Анализ принятых данных

       {

             m_ReceiveDataSize+= n;

             if (m_ReceiveDataSize == sizeof(DWORD)) // при приеме длины полностью

             {

                   m_IsReceiveSize = false;

                   m_ReceiveData.Alloc(m_ReceiveSize);

                   m_ReceiveDataSize = 0;

             }

       }

}

else

// Прием самих данных

{

       int n = Receive((BYTE*)m_ReceiveData.GetAddr()+m_ReceiveDataSize, m_ReceiveSize-m_ReceiveDataSize);

       // Анализ ошибок

       if (n == SOCKET_ERROR)

       {

             ErrCode = GetLastError();

             if (ErrCode != WSAEWOULDBLOCK)

             {

                   CString s;

                   s.Format("Ошибка при приеме собщения! Код ошибки %u", ErrCode);

                   MessageBox(0,s,"Сообщение",MB_OK);

                   Close();

             }

       }

       else

       // Анализ принятых данных

       {

             m_ReceiveDataSize+= n;

             if (m_ReceiveDataSize == m_ReceiveSize) // при завершении приема пакета

             {

                   m_ReceiveDataSize = 0;

                   m_IsReceiveSize = true;

                   //AfxMessageBox("Принят пакет!");

                   OnReceivePacket();

             }

       }

 

}

}

Способы закрытия сетевого соединения между сокетами.

Как оказалось, их 3:

  1. Соединение разрывается по инициативе самого сокета; Функция Close();
  2. Соединение разрывается при получении команды от удаленного сокета о разрыве соединения; Событие OnClose();
  3. Соединение разрывается при обрыве линии связи.

Типы сокетов. Область их применения.

Сокетом (от англ. socket - гнездо, розетка) называется специальный объект, создаваемый для отправки и получения данных через сеть. Этот объект создаётся внутри библиотеки сокетов, а программист, использующий эту библиотеку, получает уникальный номер (дескриптор) этого сокета. Конкретное значение этого дескриптора не несёт для программиста никакой полезной информации и может быть использовано только для того, чтобы при вызове функции из библиотеки сокетов указать, с каким сокетом требуется выполнить операцию.

Чтобы две программы могли общаться друг с другом через сеть, каждая из них должна создать сокет. Каждый сокет обладает двумя основными характеристиками: протоколом и адресом, к которым он привязан. Протокол задаётся при создании сокета и не может быть изменён впоследствии. Адрес сокета задаётся позже, но обязательно до того, как через сокет пойдут данные. В некоторых случаях привязка сокета к адресу может быть неявной.

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

Сокеты, независимо от вида, деляться на три типа: потоковые, сырые(windows их не "держит") и дейтаграммные. Потоковые сокеты работают с установкой соединения, обеспечивая надежную идентификацию обеих сторон и гарантируют целостность и успешность доставки данных, опираются на протокол TCP. Дейтаграммные сокеты работают без установки соединения и не обеспечивают ни идентификации отправителя, ни контроля успешности доставки данных, зато они быстрее потоковых, опираються на протокол UDP. Сырые сокеты, они предоставляют возможность ручного формирования TCP\IP пакетов.

Источник:

http://tehnofil.ru/?id=91

Понятие номера порта для протоколов транспортного уровня сетевой модели OSI.

После того, как пакет средствами протокола IP доставлен в компьютер-получатель, данные необходимо направить конкретному процессу-получателю. Каждый компьютер может выполнять несколько процессов, более того, прикладной процесс тоже может иметь несколько точек входа, выступающих в качестве адреса назначения для пакетов данных.

Пакеты, поступающие на транспортный уровень, организуются операционной системой в виде множества очередей к точкам входа различных прикладных процессов. В терминологии TCP/IP такие системные очереди называются портами. Таким образом, адресом назначения, который используется на транспортном уровне, является идентификатор (номер) порта прикладного сервиса. Номер порта, задаваемый транспортным уровнем, в совокупности с номером сети и номером компьютера, задаваемыми сетевым уровнем, однозначно определяют прикладной процесс в сети.

Назначение номеров портов прикладным процессам осуществляется либо централизовано, если эти процессы представляют собой популярные общедоступные сервисы, типа сервиса удаленного доступа к файлам TFTP (Trivial FTP) или сервиса удаленного управления telnet, либо локально для тех сервисов, которые еще не стали столь распространенными, чтобы за ними закреплять стандартные (зарезервированные) номера.

Локальное присвоение номера порта заключается в том, что разработчик некоторого приложения просто связывает с ним любой доступный, произвольно выбранный числовой идентификатор, обращая внимание на то, чтобы он не входил в число зарезервированных номеров портов. В дальнейшем все удаленные запросы к данному приложению от других приложений должны адресоваться с указанием назначенного ему номера порта.










Последнее изменение этой страницы: 2018-04-12; просмотров: 204.

stydopedya.ru не претендует на авторское право материалов, которые вылажены, но предоставляет бесплатный доступ к ним. В случае нарушения авторского права или персональных данных напишите сюда...