Page 1 of 2 12 LastLast
Results 1 to 10 of 15

Thread: Sockets unit in Lazarus

  1. #1

    Smile Sockets unit in Lazarus

    I was looking at documentation for this unit called "Sockets" in Lazarus. It gave me 2 example units: server and client. Client compiled fine but Server did not. The reason: this line of code:

    if not Accept(S, FromName, Sin, Sout) then
    PError('Server : Accept : '+fromname) ;

    (find the full example here: http://www.freepascal.org/docs-html/.../fpaccept.html its at the bottom)

    From what I can understand, the Accept function is deprecated, which makes sense since it won't compile anyways because FromName is a string and it wants something else.

    Could someone help me problem solve and replace this line of code with the non-deprecated one: fpAccept. I would be so greatful!

  2. #2
    The examples are ancient history, back to a time where they implemented socket-to-file functions, which are now deprecated. Now, they just pass-through to the underlying API socket calls, so those won't compile anymore without recompiling the sockets unit with the legacy symbol defined.

    I've had issues with the FP sockets unit being incomplete/wrong in the past. I ended up using my own instead.

    If you just want to do it with the sockets unit, no fancy textfile-handling (which is annoying anyway), this should come closer to what you are looking for:

    Code:
    Program Server;
    
    Uses Sockets;
    
    Var
      Buffer           : String[255];
      Count            : LongInt;
      ClientSocket     : Longint;
      ListenSocket     : Longint;
      ServerAddr       : TInetSockAddr;
      ClientAddr       : TInetSockAddr;
      ClientAddrSize   : LongInt;
    
    Procedure PrintError (Const Msg : String);
      Begin
      Writeln (Msg,SocketError);
      Halt(100);
      End;
    
    Begin
      ListenSocket := fpSocket (AF_INET,SOCK_STREAM,0);
      If ListenSocket = SOCKET_ERROR Then
        PrintError ('Server : Socket : ');
      ServerAddr.sin_family := AF_INET;
      { port 50000 in network order }
      ServerAddr.sin_port := htons(50000);
      ServerAddr.sin_addr.s_addr := htonl($7F000001);
      If fpBind(ListenSocket,@ServerAddr,sizeof(ServerAddr)) = SOCKET_ERROR Then
       PrintError ('Server : Bind : ');
      If fpListen (ListenSocket,1) = SOCKET_ERROR Then
       PrintError ('Server : Listen : ');
      Writeln('Waiting for Connect from Client, run now sock_cli in an other tty');
      ClientAddrSize := sizeof(ClientAddr);
      ClientSocket := fpaccept(ListenSocket,@ClientAddr,@ClientAddrSize);
      If ClientSocket = SOCKET_ERROR Then
       PrintError('Server : Accept : ');
      Buffer := 'Message From Server';
      Count := Length(Buffer);
      If (fpsend(ClientSocket,@Buffer[1],Count,0) = Count) Then
        Begin
        Repeat
          Count := fprecv(ClientSocket,@Buffer[1],255,0);
          If (Count <> SOCKET_ERROR) And (Count > 0) Then
            Begin
            SetLength(Buffer,Count);
            Writeln('Server : read : ',Buffer);
            End;
        Until (Count = SOCKET_ERROR) Or (Count = 0);
        End;
      CloseSocket(ClientSocket);
      CloseSocket(ListenSocket);
    End.
    Code:
    Program Client;
    
    Uses Sockets;
    
    Procedure PrintError(Const Msg : String);
      Begin
      Writeln(Msg,SocketError);
      Halt(100);
      End;
    
    
    Var
      ServerAddr       : TInetSockAddr;
      Buffer           : String[255];
      ServerSocket     : Longint;
      Count            : Longint;
      I                : Integer;
    
    Begin
      ServerSocket := fpSocket(AF_INET,SOCK_STREAM,0);
      If ServerSocket = SOCKET_ERROR Then
       PrintError('Client : Socket : ');
      ServerAddr.sin_family := AF_INET;
      { port 50000 in network order }
      ServerAddr.sin_port := htons(50000);
      { localhost : 127.0.0.1 in network order }
      ServerAddr.sin_addr.s_addr :=htonl($7F000001);
      If fpconnect(ServerSocket,@ServerAddr,Sizeof(ServerAddr)) = SOCKET_ERROR Then
       PrintError('Client : Connect : ');
      Buffer := 'This is a textstring sent by the Client.';
      For I := 1 To 10 Do
        Count := fpsend(ServerSocket,@Buffer[1],Length(Buffer),0);
      Count := fprecv(ServerSocket,@Buffer[1],255,0);
      if Count <> SOCKET_ERROR Then
        Begin
        SetLength(Buffer,Count);
        Writeln('Server sent: ',Buffer);
        End;
      CloseSocket(ServerSocket);
    End.
    Last edited by Murmandamus; 04-03-2011 at 05:19 PM.

  3. #3
    This code looks great and compiles! That makes me so happy =) except one problem/my not understanding cause I'm horrible with anything to do with networking. When I run the server it says Server: Socket: 0 then finishes. Is this intended? Again, I'm sorry for knowing so little, I'm trying to learn =P

    Once again thank you for your help!

  4. #4
    Bleh.. had a copy/paste error in the server. Sorry about that; that code is likely not bug-free, I just syntax-checked it to be sure the compiler wouldn't barf on it. It is one of my personal rules about providing examples. I edited the server code to fix that bug. Try it now and see if it works. There may be an issue with the way I am handling the string buffer, but it should work.

  5. #5
    Yeah it doesn't look like its sending the string buffer to the client. When I run the server it says this:

    Waiting for Connect from Client, run now sock_cli in an other tty
    Server : Accept : 10014

    Then it instantly finishes, not sending any buffers or anything. The client runs and simply says:

    Client : Connect : 10061

    Then finishes. *boggle*

  6. #6
    Just a general tip for all who want to do network programming: Install wireshark and learn how to use it. It allows you to monitor your network traffic with great detail.

    During my computer networks course at university, I had to do some programming assignments and wireshark helped me ALOT there.
    Coders rule nr 1: Face ur bugz.. dont cage them with code, kill'em with ur cursor.

  7. #7
    Chronozphere: Yeah, a sniffer can be helpful once you get to where you are exchanging traffic and are having issues with sending/receiving.

    Nick: It looks like the server socket address wasn't being set in the server. Those numbers you see are Winsock errors, and you can look them up in the header files or on the internet (google "winsock errors"). 10014 is "Bad Address" on the Accept, and indeed, the server code set the address for the server socket to 0 (again, that example code in the FP help is awful). 10061 is "Connection refused", which is exactly the error you should get if the server isn't running.

    I also went ahead and tested it myself this time, and the updated version of both the client and server works OK. So now you can ask questions about what it is doing, if you like.

  8. #8
    It works! My god it works! =) Very good work, you guys are awesome. I will reply here if I run into any more problems while implementing it into my own programs. Thank you!

  9. #9
    One baby step further: how can I make the server not shut off when a client connects? I'd like to have a server always running while clients connect and send different buffers to the server. Not sure how difficult this would be to do =] I tried to figure it out but ended up making the server crash lol

  10. #10
    Well, realize that these examples are real good for demonstrating the basics of socket / network programming. However, turning them into something practical will be a long road indeed.

    The first thing you need to do is understand what is going on and why. What the various socket functions are doing, what the contents of the data structures are, and what order you need to use to do any particular thing.

    Complex client/server network apps are also often multi-threaded, which throws a-whole-nother dimension of complexity into the mix, but we can get into that later.

    So, let's start with getting you real familiar with what is going on with the examples, then we can step up to more complex functionality when you're ready. Study the examples, and read a bit through the (windows or linux) socket documentation; you can find both on the internet with a simple google search on Winsock (the MSDN documentation is best) or unix sockets. Bookmark these resources, because you will be referencing them often in development.
    Last edited by Murmandamus; 05-03-2011 at 06:45 PM. Reason: typo

Page 1 of 2 12 LastLast

Tags for this Thread

Bookmarks

Posting Permissions

  • You may not post new threads
  • You may not post replies
  • You may not post attachments
  • You may not edit your posts
  •