digitalmars.D - Problem with SocketStream.readLine
- Michael Butscher (104/104) Apr 28 2005 Hi,
- Ben Hinkle (13/33) Apr 28 2005 Interesting. I don't know much about sockets but the socketstream.readli...
- Charlie (8/49) Apr 28 2005 Hmm, win32 and linux both use \n as the 'last' char to denote a new line...
- Ben Hinkle (11/13) Apr 28 2005 The trouble is that mac line endings might be coming down the stream and...
- Vathix (8/11) Apr 29 2005 While I was running your code I noticed the client will start working
- Michael Butscher (5/10) Apr 29 2005 It seems that it works (at least better), if the server pauses a bit bet...
Hi, could please somebody explain me why the following code doesn't work properly? It was tested on Windows ME, so you have to link with ws2_32.lib to compile it. The code starts 2 threads, a server and a client which communicate by a TCP socket. The client sends a single line (ending with "\r\n") as a request to the server, the server reads it and responds with exactly 100000 bytes of data, but the client receives only a part of the data. Curiously, the code works perfectly well if the request string only ends with "\n". After I replaced SocketStream.readLine() with a slightly modified function which ignores "\r" characters, it worked also. Thanks in advance Michael The code: -------------------------------------------------- import std.socket; import std.socketstream; import std.stream; import std.thread; const char[] IP = "127.0.0.1"; // Address to use for connection const int PORT = 2000; // Port to use const int TESTLENGTH = 100000; // Length of test data const ubyte[TESTLENGTH] testbuffer; // Data to send from server to client // Request string to send from client to server: const char[] REQSTRING = "Testing\r\n"; // Does not work // const char[] REQSTRING = "Testing\n"; // Works (Missing '\r') int serve() // Server function { auto Socket listener = new TcpSocket(); listener.bind(new InternetAddress(IP, PORT)); listener.listen(10); Socket sock; while (true) { try { sock = listener.accept(); printf("Request\n"); sock.blocking = true; SocketStream stream = new SocketStream(sock); stream.readLine(); // Read request int sent = stream.write(testbuffer); // Send data sock.shutdown(SocketShutdown.BOTH); sock.close(); printf("Sent: %i\n", sent); } catch (Exception exc) { printf("Server Error\n"); exc.print(); } } } void request() // Client function { while(true) { int i = 0; try { Socket sock = new TcpSocket(new InternetAddress(IP, PORT)); SocketStream stream = new SocketStream(sock); char buffer; stream.write(cast(ubyte[])REQSTRING); // Send request while(true) { stream.read(buffer); // Read data ++i; } } catch (Exception exc) { printf("Read: %i\n", i); } } } int main(char[][] args) { int runreq() { request(); return 0; } int runserv() { serve(); return 0; } Thread t; if (args.length == 1 || args[1] == "s") // Server only { t = new Thread(&runserv); t.start(); } if (args.length == 1 || args[1] == "c") // Client only { t = new Thread(&runreq); t.start(); } t.wait(); return 0; } --------------------------------------------------
Apr 28 2005
Interesting. I don't know much about sockets but the socketstream.readline doesn't read the last \n when it sees the \r - it leaves it in the stream until the next read. I assume that's because readLine doesn't actually know if there is a \n coming and it doesn't want to block waiting for one. It seems, though, that leaving that char in the stream gets in the way of future send/recv calls. It doesn't matter what that last char is or if it just reads an incomplete amount of data. Is there a way to know if the line ending is \r or \r\n ahead of time or is there some setting on the socket that will fix it? Again I don't know the details of how sockets send and recieve so someone else besides me will have to help out (I generally take generic stream questions but this one seems out of my realm). "Michael Butscher" <mbutscher gmx.de> wrote in message news:MPG.1cdb6332bdc3cce0989681 news.digitalmars.com...Hi, could please somebody explain me why the following code doesn't work properly? It was tested on Windows ME, so you have to link with ws2_32.lib to compile it. The code starts 2 threads, a server and a client which communicate by a TCP socket. The client sends a single line (ending with "\r\n") as a request to the server, the server reads it and responds with exactly 100000 bytes of data, but the client receives only a part of the data. Curiously, the code works perfectly well if the request string only ends with "\n". After I replaced SocketStream.readLine() with a slightly modified function which ignores "\r" characters, it worked also. Thanks in advance Michael
Apr 28 2005
Hmm, win32 and linux both use \n as the 'last' char to denote a new line, probably should use this ? Charlie "Ben Hinkle" <ben.hinkle gmail.com> wrote in message news:d4rt0d$229n$1 digitaldaemon.com...Interesting. I don't know much about sockets but the socketstream.readline doesn't read the last \n when it sees the \r - it leaves it in the stream until the next read. I assume that's because readLine doesn't actuallyknowif there is a \n coming and it doesn't want to block waiting for one. It seems, though, that leaving that char in the stream gets in the way of future send/recv calls. It doesn't matter what that last char is or if it just reads an incomplete amount of data. Is there a way to know if thelineending is \r or \r\n ahead of time or is there some setting on the socket that will fix it? Again I don't know the details of how sockets send and recieve so someone else besides me will have to help out (I generally take generic stream questions but this one seems out of my realm). "Michael Butscher" <mbutscher gmx.de> wrote in message news:MPG.1cdb6332bdc3cce0989681 news.digitalmars.com...functionHi, could please somebody explain me why the following code doesn't work properly? It was tested on Windows ME, so you have to link with ws2_32.lib to compile it. The code starts 2 threads, a server and a client which communicate by a TCP socket. The client sends a single line (ending with "\r\n") as a request to the server, the server reads it and responds with exactly 100000 bytes of data, but the client receives only a part of the data. Curiously, the code works perfectly well if the request string only ends with "\n". After I replaced SocketStream.readLine() with a slightly modifiedwhich ignores "\r" characters, it worked also. Thanks in advance Michael
Apr 28 2005
"Charlie" <charles jwavro.com> wrote in message news:d4rtoi$2309$1 digitaldaemon.com...Hmm, win32 and linux both use \n as the 'last' char to denote a new line, probably should use this ?The trouble is that mac line endings might be coming down the stream and you don't know before-hand. Just because the code reading the stream is on win32 or linux doesn't mean the code that wrote to the stream is using that platform's line endings. The general Stream class does a getc when it sees a \r to scarf up any following \n and it has always bothered me that the getc might block as it waits for the next char. Maybe the right thing to do is put some "peeking" code into streamsocket that scarfs up the \n if it is available. Does anyone know if the \n will always be peekable if one is there?
Apr 28 2005
On Thu, 28 Apr 2005 16:17:15 -0400, Michael Butscher <mbutscher gmx.de> wrote:Hi, could please somebody explain me why the following code doesn't work properly?While I was running your code I noticed the client will start working correctly if the console has focus for awhile and/or if you hit enter or move the mouse over it. I even rewrote it to not use the SocketStream and still ran into read problems on the client side. I'll mess around with it some more. - Chris
Apr 29 2005
Vathix wrote:While I was running your code I noticed the client will start working correctly if the console has focus for awhile and/or if you hit enter or move the mouse over it. I even rewrote it to not use the SocketStream and still ran into read problems on the client side. I'll mess around with it some more.It seems that it works (at least better), if the server pauses a bit between sending data and closing the socket (e. g. by a dummy for-loop) Michael
Apr 29 2005