[Gambas-user] Socket Limitations

Doriano Blengino doriano.blengino at ...1909...
Sun Jan 3 20:59:24 CET 2010


Benoît Minisini ha scritto:
>> Benoît Minisini ha scritto:
>>     
>>>> [lot of talk]
>>>>         
>>> The point of view of the client and the server are not the same:
>>>
>>> The client likes blocking socket. It usually asks or sends something to
>>> the server, waits for the answer, and so on... It usually does one thing
>>> at once.
>>>
>>> On the contrary, the server should serve multiple client connection at
>>> once. Then it should use non-blocking sockets, and send data to the
>>> client only when the socket raises its Write event, meaning that the OS
>>> has told Gambas that the internal socket write buffer has space in it.
>>>
>>> The timeout is managed by the OS: I can only offer a property to define
>>> it, as in other languages, but that should change nothing to the logic of
>>> the program.
>>>
>>> <Kadaicha irony mode>
>>>
>>> I'm not sure that the MSDN documentation is a good reference for socket
>>> programming:
>>>
>>> - The Microsoft documentation is often not connected to the reality it
>>> tries to describe.
>>>
>>> - The Windows socket implementation often behaves differently than the
>>> other OS implementation.
>>>
>>> </Kadaicha irony mode>
>>>
>>> My problem is: how can I have the easier Socket interface in Gambas for
>>> all possible socket scenarii?
>>>
>>> That is the reason why I said that if the user asks for writing a big
>>> chunk of data to the socket, I should temporarily other blocking mode.
>>> Maybe he is doing something wrong (i.e. using a non-blocking socket, but
>>> not the Write event), but Gambas can't be sure.
>>>
>>> Gambas 2 behave this way (not my decision), and I removed this behaviour
>>> in Gambas 3, but now I don't remember why. I should test all the
>>> scenarii...
>>>
>>> Regards,
>>>       
>> Ok, it just came to my mind another possible way. The problem is that
>> even having a "write" event, if you try to send out 128K bytes the write
>> will not succed in one step. The same for reading - if you want to read
>> a line, the OS will tell you that there is something to read, but not
>> how much and neither if the incoming data contain a CR-LF or not. So
>> there could be a way where you, in gambas, "write #xx" any amount of
>> data. When the operation completes, an event is fired, where you can
>> issue another write or shutdown the socket. 
>>     
>
> It will be too complex at the moment. That means internally managing 
> asynchronous I/O.
>   
No asynchronous I/O would be involved; instead of simply reflect the 
operating system event (or polling) to the gambas program, the 
interpreter could manage internally until the requested condition is met 
(readed a full line; or: sended all the requested bytes), and only then 
raise an event to the gambas program. In fact, this would be possible 
right now, with the current gambas capabilities, by a class written in 
gambas. I could also try, but I am very busy with other tasks.
> The simpler is being able to know how much data has been actually written 
> after a Write call.
>   
Right.
> For the read part, you are wrong: Lof() will tell you how much data you can 
> read, and, moreover, Read has a special syntax to read up to a defined number 
> of bytes. And you know then how much data you read, because you get it in 
> memory.
>   
I was referring to the OS, not to gambas; anyway there must be a way to 
know how many bytes are ready to be read, but the operating system will 
not tell you if a whole line is ready. I took a look to gbx_stream.c, 
and found that to read a line (line input?), a for (;;) is used which, I 
think, is blocking. My idea was to raise an event when a line has been 
read, instead of blocking or make a buffering.
> I'm currently thinking on a dedicated property of the Stream class, whose name 
> could be "Written" or something like that. You will use it just after the 
> Write call. Or, maybe, the Write instruction could return it as an integer.
>
>   
>> Reading is a little
>> trickyer, because the normal syntax implies that the value you read is
>> available just after; in this case, one should "declare" that he wants
>> to read a line, or a certain number of bytes, and when the event fires
>> the data are ready to be used; in the same event you can issue another
>> read, and so on. This is not a new idea, anyway.
>>
>> The timeout, as seen in this discussion, could be settable for error
>> raising purposes, and the blocking mode is handy to write simple
>> programs without event management.
>>
>> Just now I am writing a program which interfaces with gdb using pipes -
>> this can be a good test to explore my idea; in fact I tried at first
>> with blocking mode; then, not happy, tried non blocking mode with
>> events; but trying to read whole lines of text does not work the way I
>> want because still I find myself writing cycles
>>     
>
> What do you mean by "writing cycle" ?
>
> If you want to interface with a program having I/O line-based, you must manage 
> your own buffer in the read event, because you cannot never be sure that you 
> will receive a full line of data (with the newline character at the end). So 
> you must store the received data in a local buffer, and then extract lines 
> from this buffer when it is possible.
>
> Regards,
>
>   
And this is what I am doing right now, using GLIB channels (sorry, not 
gambas related). An event is fired as soon as some data can be read, but 
you don't know how much data is available (or, at least, I do not know 
how to do it). So I set the channel non-blocking, read the available 
data and append it in the buffer, but at this point I can have 0, 1, or 
more lines ready - in just an event. I would like an event for every 
line, and this is why I suggested the same for gambas. This is already 
possible, of course. I wrote in gambas a file manager with external 
plugins made in bash, using the normal approach (the one you suggest). 
Again, for a text-line-based communication, an event for every line read 
would sometimes make sense.

Regards,

-- 
Doriano Blengino

"Listen twice before you speak.
This is why we have two ears, but only one mouth."





More information about the User mailing list