Logo Море(!) аналитической информации!
IT-консалтинг Software Engineering Программирование СУБД Безопасность Internet Сети Операционные системы Hardware
Архив форумов ЦИТФорума
Море(!) вопросов - Море(!) ответов
 
 FAQFAQ   ПоискПоиск   ПользователиПользователи   ГруппыГруппы   РегистрацияРегистрация 
 ПрофильПрофиль   Войти и проверить личные сообщенияВойти и проверить личные сообщения   ВходВход 
Как правильно задавать вопросы

understanding windows sockets

 
Перейти:  
Этот форум закрыт, вы не можете писать новые сообщения и редактировать старые.   Эта тема закрыта, вы не можете писать ответы и редактировать сообщения.    Список форумов Архив форумов ЦИТФорума -> Программирование
Предыдущая тема :: Следующая тема  
Автор Сообщение
adonin



Зарегистрирован: 11.10.2005
Сообщения: 35

СообщениеДобавлено: Ср Ноя 23 2005 16:29    Заголовок сообщения: understanding windows sockets Ответить с цитатой

Сервер принимает 3 соединения от клиентов (соединение по TCP):
Код:

listen(s,3);
for(i=0;i<3;i++)
{
    scl[i]=accept(s,(sockaddr*)&sacl[i],NULL);
    send(scl[i],str,k,0);
}


Получается, что у сервера 3 сокета на одном порту? Или нет?
Каким образом поддерживается несколько соединений TCP через один порт? Используются свободные порты?
ИМХО сокет однозначно определяется IP и номером порта, или нет? Объясните!

ЗЫ. Пробовал на клиентах получить адреса сервера через recvfrom, но там структура заполняется нулями:
Код:

for(i=0;i<3;i++)
{
    s[i]=socket(PF_INET,SOCK_STREAM,IPPROTO_TCP);
    bind(s[i],(sockaddr*)&sa,sizeof(sa));           
    connect(s[i],(sockaddr*)&saconn,sizeof(saconn));
    recvfrom(s[i],buf,600,0,(sockaddr*)&sfrom[i],&k);      // в sfrom нули :(
    sa.sin_port++;             
}
Вернуться к началу
Посмотреть профиль Отправить личное сообщение
PolAR



Зарегистрирован: 01.11.2004
Сообщения: 133

СообщениеДобавлено: Ср Ноя 23 2005 21:45    Заголовок сообщения: Ответить с цитатой

Сокет - это действительно пара IP:port.
А соединение однозначно определяется парой сокетов : IP_cli:port_cli - IP_srv:port_srv.
Поэтому када цепляется очередной клиент, сервер порождает поток ( или процесс ) для работы с данным конкретным клиентом. Этот поток ( процесс ) обслуживает уже конкретное установленное соединение IP_cli:port_cli-IP_srv:port_srv. И все пакеты с таким набором адресов и портов идут к данному подпроцессу сервера.
А основной процесс остается в режиме прослушивания.
_________________
Come Together!! Right Now....
Вернуться к началу
Посмотреть профиль Отправить личное сообщение
adonin



Зарегистрирован: 11.10.2005
Сообщения: 35

СообщениеДобавлено: Чт Ноя 24 2005 09:38    Заголовок сообщения: Ответить с цитатой

Спасибо! Может ещё знаешь почему recvfrom() не возвращает адрес отправителя? Раньще делал - всё работало (правда для UDP).


Цитата:
recvfrom(s[i],buf,600,0,(sockaddr*)&sfrom[i],&k); // в sfrom нули Sad
Вернуться к началу
Посмотреть профиль Отправить личное сообщение
PolAR



Зарегистрирован: 01.11.2004
Сообщения: 133

СообщениеДобавлено: Чт Ноя 24 2005 15:39    Заголовок сообщения: Ответить с цитатой

По-моему косяк у тебя здесь:
Код:
for(i=0;i<3;i++)
{
    s[i]=socket(PF_INET,SOCK_STREAM,IPPROTO_TCP);
    bind(s[i],(sockaddr*)&sa,sizeof(sa));           
    connect(s[i],(sockaddr*)&saconn,sizeof(saconn));
    recvfrom(s[i],buf,600,0,(sockaddr*)&sfrom[i],&k);      // в sfrom нули :(
    sa.sin_port++;             
}

Конкретно в строчке:
Код:
    bind(s[i],(sockaddr*)&sa,sizeof(sa));           

Системный вызов bind выполняется для сервера и связывает его сокет с портом для последующего прослушивания
Клиенту достаточно:
Код:
 s[i]=socket(PF_INET,SOCK_STREAM,IPPROTO_TCP);
connect(s[i],(sockaddr*)&saconn,sizeof(saconn));

Где saconn - структура, соответствующая сокету сервера, к которому цепляемся!

Я не утверждаю, потому что подзабыл уже ( 2 года назад вскольз программировал )
Когда разберешься - запости!
_________________
Come Together!! Right Now....
Вернуться к началу
Посмотреть профиль Отправить личное сообщение
adonin



Зарегистрирован: 11.10.2005
Сообщения: 35

СообщениеДобавлено: Чт Ноя 24 2005 17:30    Заголовок сообщения: Ответить с цитатой

Спасибо за помощь, я уже разобрался. Просто recvfrom() не возвращает адрес для сокетов TCP. Она сработает для сокетов, для которых не устанавливалось соединение TCP. (UDP, Raw Sockets).
А насчет bind() ты не прав. bind() привязывает сокет к порту на локальной машине. После bind() ни один процесс в системе не может использовать этот порт. Значение порта, указанного в bind() подставляется в поле Local Port заголовка IP пакета.
Вернуться к началу
Посмотреть профиль Отправить личное сообщение
PolAR



Зарегистрирован: 01.11.2004
Сообщения: 133

СообщениеДобавлено: Пт Ноя 25 2005 07:09    Заголовок сообщения: Ответить с цитатой

Цитата:

А насчет bind() ты не прав. bind() привязывает сокет к порту на локальной машине. После bind() ни один процесс в системе не может использовать этот порт. Значение порта, указанного в bind() подставляется в поле Local Port заголовка IP пакета.

Как я понимаю эта возможность нужна искл. для серверов, а клиент берет первый попавшийся свободный порт > 1024 ( а откуда ты знаешь какой сейчас свободен??? => ты не можешь заранее сформировать sockaddr, который передается в bind!!).
А вот connect знает какие порты щас свободны, его займет и вернет тебе sockaddr в структуру, адрес на которую ты передаешь в connect вторым параметром - saconn
_________________
Come Together!! Right Now....
Вернуться к началу
Посмотреть профиль Отправить личное сообщение
adonin



Зарегистрирован: 11.10.2005
Сообщения: 35

СообщениеДобавлено: Пт Ноя 25 2005 11:00    Заголовок сообщения: Ответить с цитатой

см. MSDN:

Цитата:

Remarks
The bind function is used on an unconnected socket before subsequent calls to the connect or listen functions. It is used to bind to either connection-oriented (stream) or connectionless (datagram) sockets. When a socket is created with a call to the socket function, it exists in a name space (address family), but it has no name assigned to it. Use bind to establish the local association of the socket by assigning a local name to an unnamed socket.
Cool

Итак, перед connect() тоже надо делать dind(). Wink
А насчёт узнать какие порты свободны - существует список распространённых программ, в котором указаны используемые ими порты. Просто не использовать в своих приложениях эти порты. При этом после bind() делаем WSAGetLastError(), если !=0 делаем инкремент номера порта и повторяем bind().

З.Ы. второй параметр в connect() - адрес удаленного хоста (куда конектиться), и является входным. См. MSDN:
Цитата:

name
[in] The name of the socket to connect to.
Вернуться к началу
Посмотреть профиль Отправить личное сообщение
PolAR



Зарегистрирован: 01.11.2004
Сообщения: 133

СообщениеДобавлено: Сб Ноя 26 2005 10:06    Заголовок сообщения: Ответить с цитатой

Я В Линухе программировал это и в клиентах bind не использовал - но все работало.
А насчет connect-a я ла#анулся.
Хорошо что у тебя все поперло! Удачи
_________________
Come Together!! Right Now....
Вернуться к началу
Посмотреть профиль Отправить личное сообщение
Показать сообщения:   
Этот форум закрыт, вы не можете писать новые сообщения и редактировать старые.   Эта тема закрыта, вы не можете писать ответы и редактировать сообщения.    Список форумов Архив форумов ЦИТФорума -> Программирование Часовой пояс: GMT + 3
Страница 1 из 1

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


Powered by phpBB © 2001, 2002 phpBB Group
Русская поддержка phpBB

 

IT-консалтинг Software Engineering Программирование СУБД Безопасность Internet Сети Операционные системы Hardware

Информация для рекламодателей PR-акции, размещение рекламы — adv@citforum.ru,
тел. +7 495 6608306, ICQ 232284597
Пресс-релизы — pr@citforum.ru
Послать комментарий
Информация для авторов
This Web server launched on February 24, 1997
Copyright © 1997-2000 CIT, © 2001-2006 CIT Forum
Внимание! Любой из материалов, опубликованных на этом сервере, не может быть воспроизведен в какой бы то ни было форме и какими бы то ни было средствами без письменного разрешения владельцев авторских прав. Подробнее...