Автор
|
Тема: ServerSocket
|
leha |
опубликован 14-11-2001 11:58 MSK
Сокет не блокируемый, как на Accept со стороны клиента сказать что мы не много заняты. Клиент у меня умный подождет, а вот сервер научиь так же не получается. выставлял флажок на время работы с данными и если в это время пришли еще делал Close. Клиент все равно передал в никуда данные :-(
|
necer
|
опубликован 14-11-2001 13:05 MSK
А это уже специфика TCP/IP. На самом деле Send не пишет данные непосредственно в удаленный сокет, а всего-лишь кладет их в буфер передачи. И возвращаемое значение есть не количество переданных байт, а сколько байт успешно положено в буфер. В описанной ситуации, как вариант, можно научить клиента сначала ждать ответа от сервера и только потом пытаться передать данные. |
leha
|
опубликован 14-11-2001 13:15 MSK
У меня так и есть, клиент проверяет конект, то есть на сервере возникает событие ServerSocketAccep. Так вот как если у меня еще идет обработка данных или другой клиент пытается законектится, сказать что я занят, делал так после клиентреад поднимал флаг и в аксепте если флаг говорил ServerSoket->Close() потом включал таймер и по падению флага опять переводил в Open, неужели нельзя проще сказать что я занят или я просто туплю. |
necer
|
опубликован 15-11-2001 10:27 MSK
Проще сказать нельзя. OnAccept возникает после того, как сервер с клиентом установили TCP соединение. И потому клиент уже разрешает передачу данных. Надо заставить клиента не передавать данные до тех пор, пока не придет разрешение от сервера не передачу. То-есть сервер, в зависимости от своего текущего состояния либо закрывает соединение, либо посылает сообщение о том, что он свободен и готов к обработке данных. |
leha
|
опубликован 15-11-2001 13:24 MSK
Все хорошо(на момент обработки данных и одновременной передачи),только эта шняга крутиться как сервис и служит для развязки данных пришедших с QNX и должна всавить их в базу, так вот на AcceptConnection проверяется а не упал ли сервер и если упал то в блоке catch делаем сокету close , а данные уже передали что не есть гуд. Как на клиенте увеличить таймаут. У меня просто if (connect(sock,&server,sizeof(server))<0 close sock done=send(sock,bufer,sizeof(bufer),0) и проверка done, так send это то что попало в буфер сервера. |
necer
|
опубликован 16-11-2001 10:44 MSK
То-есть сервер не собственного написания? Можешь объяснить, как все организовано? |
leha
|
опубликован 17-11-2001 08:11 MSK
Могу, пример из стандартной поставки Билдера \Internet\Chat переделал под свои нужды так как досканального понимания не наступило. Есть клиент работающий на промкомпьтере в системе реального времени QNX снимающий данные и создающий соединение с Windows сервером по TCP\IP передает в виде строки которая на сервере разбирается и втыкается в базу данных. Сервер как я сказал не блокируемый и для развязки с другими клиентами и на момент обработки данных по событию OnClientRead выставляем ServerSocket->Close все было зашибись до тех пор пока сервер куда данные втыкались не упал, о чем мой сервис не знал и посылал данные в никуда. Хочется теперь при запросе коннекта проверять доступна ли база, что делается выполнением хранимой процедуркой на сервер для активизации роли, и если произошла ошибка сказать клиенту что мы заняты, но как это реализовать. Я попытался во время ServerSocketAccept выполнять эту хранимую процедурку и если ошибка делать Server->Close затем по таймеру проверять поевилось соединение с базой то делаем Open, но клиент все равно шлет данные, почему не понятно я думал что клиент когда делает коннект, на сервере происходит ServerSocketAccept и я могу либо разрешить либо нет соединение так вот как это сделать я не знаю. Наверное можно научить клиента ждать какого-нибудь сообщения от сервера и только тогда делать Send, но знаний не хватает. |
Heromantor
|
опубликован 17-11-2001 13:00 MSK
ПО моему можно сделать двумя способами 1. Организовать на сервере очередь сообщений т.е. сервер принимает строку по любому, а в базу помещает ее только когда будет такая возможность. 2. Когда сервер будет готов к приему то посылать клиенту какую нибудь строчку типа "+OK Server ready", а клиент будет ждать эту строчку.Но по моему надо делать с очередью т.к. если скажем сервер скажет что готов то может возникнуть ситуация такая что за время в течение которого будут передаваться данные база будет опять занята... |
necer
|
опубликован 19-11-2001 12:13 MSK
Придется разрабатывать протокол уровня приложения (хоть и простой) независимо от того, будет использоваться очередь или нет. В любом случае, насколько я понял, клиента необходимо уведомлять: 1. О готовности сервера к приему данных 2. О завершении размещения данных в БД (успешном или нет). В общем, помимо данных клиент и сервер должны обмениваться сообщениями. Например, как совершенно справедливо заметил Heromantor, клиент не должен посылать данные, пока не получит от сервера строку (а лучше, числовое значение), подтверждающую его (сервера) готовность. И.т.д. |