Results 1 to 2 of 2

Thread: Winsock and recvfrom function

  1. #1

    Winsock and recvfrom function

    First of all i'd like to say that I'm tottally unexperienced in network programming, and speaking the truth I do not know almost nothing about networks. (that's why I'm making this post) To give you take a clue I don't really know what UDP means, some kind of protocol I suppose.

    Anyway, I use Delphi6(or greater), WinSock.pas unit and SDK functions. I do not work in a form-based enviroment, so usage of components is useless.
    Maintaining a game (DelphiDoom, as well as DelphiHeretic http://delphidoom.sitesled.com/downloads.html) I have a big problem in networking:
    After a lot of of experiments using 2 computers connected in LAN running simultaneously DelphiHeretic(and DelphiDoom) I'm managed to send packets (PacketSend procedure in i_net.pas works) but could not receive none of them (procedure PacketGet in i_net.pas does not work, recvfrom() function returns error = WSAEWOULDBLOCK) and I don't even know what does that error mean, sorry.

    To debug a network game you must run DelphiDoom/DelphiHeretic with these parameters (in 2 seperate computers):

    for DelphiDoom
    doom32.exe -net 1 addr2 -players 2 (running in computer addr1)
    doom32.exe -net 2 addr1 -players 2 (running in computer addr1)

    for DelphiHeretic
    heretic32.exe -net 1 addr2 -players 2 (running in computer addr1)
    heretic32.exe -net 2 addr1 -players 2 (running in computer addr1)

    where addr1/addr2 is the computer name or IP address of the computer you want to comunicate.

    As I'm totally unexperienced in networking I have the feeling that only if someone take a look in i_net.pas and make the apropriate changes the network code is going to work. Of cource I will be glad to credit anyone that will solve my problem (sorry guys, no money )

    To avoid downloading the source code, the unit i_net.pas is here:
    (even that I doubt that if someone looking only to the source code will find the error, but how knows).

    Thanks in advance and sorry for being so lengthy.

    [pascal]

    unit i_net;

    interface

    {
    i_net.h, i_net.c
    }

    // Emacs style mode select -*- C++ -*-
    //-----------------------------------------------------------------------------
    //
    // $Id:$
    //
    // Copyright (C) 1993-1996 by id Software, Inc.
    //
    // This source is available for distribution and/or modification
    // only under the terms of the DOOM Source Code License as
    // published by id Software. All rights reserved.
    //
    // The source is distributed in the hope that it will be useful,
    // but WITHOUT ANY WARRANTY; without even the implied warranty of
    // FITNESS FOR A PARTICULAR PURPOSE. See the DOOM Source Code License
    // for more details.
    //
    // DESCRIPTION:
    // System specific network interface stuff.
    //
    //-----------------------------------------------------------------------------

    { Called by D_DoomMain. }

    procedure I_InitNetwork;

    procedure I_ShutDownNetwork;

    procedure I_NetCmd;

    implementation

    uses
    WinSock,
    d_delphi,
    doomtype,
    d_event, d_net, d_net_h, d_player, d_ticcmd,
    g_game,
    i_system,
    m_argv,
    r_main,
    tables,
    doomstat;

    const
    MAPPED_PACKETS_PER_NODE = 32;
    NUM_MAPPED_PACKETS = (MAPPED_PACKETS_PER_NODE * MAXNETNODES);

    IPPORT_USERRESERVED = 5000;

    var
    DOOMPORT: word = (IPPORT_USERRESERVED + 29);

    sendsocket: TSocket;
    insocket: TSocket;

    sendaddress: array[0..MAXNETNODES - 1] of TSockAddrIn;

    MappedNode: integer = -1;

    type
    packetpacket_t = record
    from: integer;
    _to: integer;
    dd: doomdata_t;
    end;

    socklen_t = integer;

    const
    NO_PACKET = -1;

    type
    mapfileheader_t = record
    numnodes: integer;
    packets: array[0..MAXNETNODES - 1] of integer;
    numpackets: array[0..MAXNETNODES - 1] of integer;
    free: integer;
    end;
    Pmapfileheader_t = ^mapfileheader_t;

    mapfilepacket_t = record
    next: integer;
    from: integer;
    length: integer;
    data: doomdata_t;
    end;
    Pmapfilepacket_t = ^mapfilepacket_t;

    {var
    hMemoryMap: integer = 0;
    pSharedMemory: PByteArray = nil;
    pSharedHeader: Pmapfileheader_t;
    SharedPackets: Pmapfilepacket_t;
    hNetMutex: integer = 0;}

    var
    netget: PProcedure;
    netsend: PProcedure;

    const
    NDF_DRONE = $01;
    NDF_LEFT = $02;
    NDF_RIGHT = $04;
    NDF_BACK = $08;
    NDF_DEATHMATCH = $10;
    NDF_DEATH2 = $20;
    NDF_SPLITONLY = $40;

    procedure I_CheckIfDrone(const flags: integer);
    begin
    if (M_CheckParm('-left') > 0) or (flags and NDF_LEFT <0> 0) or (flags and NDF_RIGHT <0> 0) or (flags and NDF_BACK <0> 0) or (flags and NDF_DRONE <> 0) then
    doomcom.drone := 1;
    end;

    //
    // UDPsocket
    //
    function UDPsocket: TSocket;
    begin
    // allocate a socket
    result := socket(PF_INET, SOCK_DGRAM, IPPROTO_UDP);
    if result = INVALID_SOCKET then
    I_Error('UDPsocket(): Can''t create socket.');
    end;

    //
    // BindToLocalPort
    //
    procedure BindToLocalPort(s: TSocket; port: integer);
    var
    v: integer;
    address: TSockAddrIn;
    begin
    ZeroMemory(@address, SizeOf(TSockAddrIn));
    address.sin_family := AF_INET;
    address.sin_addr.s_addr := INADDR_ANY;
    address.sin_port := port;

    v := bind(s, address, SizeOf(TSockAddrIn));
    if v = SOCKET_ERROR then
    I_Error('BindToLocalPort(): Failed.');
    end;

    //
    // PacketSend
    //
    procedure PacketSend;
    var
    c: integer;
    begin
    c := sendto(sendsocket, netbuffer, doomcom.datalength, 0,
    sendaddress[doomcom.remotenode], SizeOf(sendaddress[doomcom.remotenode]));

    if c = SOCKET_ERROR then
    I_Error('PacketSend(): sendto() failed.');
    end;

    function FindNode(const address: TSockAddrIn): integer;
    var
    i: integer;
    begin
    // find remote node number
    i := 0;
    while i <doomcom>= 0) then
    begin
    // The remote node aborted unexpectedly, so pretend it sent an exit packet
    printf('The connection from node %d was dropped'#13#10, [node]);

    c := 1;
    end
    else if err <> WSAEWOULDBLOCK then
    begin
    I_Error('PacketGet() failed.');
    end
    else
    begin
    doomcom.remotenode := -1; // no packet
    exit;
    end;
    end;

    i := 0;
    while i <doomcom> 0 then
    begin
    portpart := Copy(remotename, p + 1, Length(remotename) - p);
    port := atoi(portpart);
    if port = 0 then
    begin
    printf('AddNodeAddress(%s): Weird port: %s (using %d)'#13#10, [remotename, portpart, DOOMPORT]);
    port := DOOMPORT;
    end
    end
    else
    port := DOOMPORT;

    addr.sin_port := htons(port);

    if remotename[1] = '.' then
    addr.sin_addr.s_addr := inet_addr(PChar(Copy(remotename, 2, Length(remotename) - 1)))
    else
    begin
    isnamed := false;
    for i := 1 to Length(remotename) do
    begin
    if not (remotename[i] in ['0', '1', '2', '3', '4', '5', '6', '7', '8', '9', '.']) then
    begin
    isnamed := true;
    break;
    end;
    end;

    if not isnamed then
    begin
    addr.sin_addr.s_addr := inet_addr(PChar(remotename));
    printf('Node number %d address %s'#13#10, [doomcom.numnodes, remotename]);
    end
    else
    begin
    hostentry := gethostbyname(PChar(remotename));
    if hostentry = nil then
    I_Error('gethostbyname(): Could not find %s'#13#10, [remotename]);
    addr.sin_addr.s_addr := PInteger(hostentry.h_addr_list)^;
    printf('Node number %d hostname %s'#13#10,
    [doomcom.numnodes, StringVal(hostentry.h_name)]);
    end;
    end;

    if addr.sin_addr.s_addr = u_long(INADDR_NONE) then
    I_Error('AddNodeAddress(): Unknown Host (%s)', [remotename]);
    end;

    procedure I_InitPacketNetworkStart;
    var
    wsad: WSADATA;
    begin
    printf(' Multiplayer'#13#10);

    netgame := true;

    if WSAStartup($0101, wsad) <0> 0 then
    while (i < myargc) and (myargv[i][1] <do> 0) and (p < myargc - 1) then
    begin
    DOOMPORT := atoi(myargv[p + 1]);
    printf('Using Port %d'#13#10, [DOOMPORT]);
    end;

    inc(i);

    if i <myargc> 0) and (p <myargc> 0) and (p < myargc - 1) then
    begin
    doomcom.ticdup := Ord(myargv[p + 1][1]) - Ord('0');
    if doomcom.ticdup <1> 9 then
    doomcom.ticdup := 9;
    end
    else
    doomcom.ticdup := 1;

    if M_CheckParm('-extratic') <0> 0 then
    begin
    I_InitCLNetwork(p);
    exit;
    end;

    printf(' Single Player'#13#10);
    // single player game
    netgame := false;
    doomcom.id := DOOMCOM_ID;
    doomcom.numplayers := 1;
    doomcom.numnodes := 1;
    doomcom.deathmatch := 0;
    doomcom.consoleplayer := 0;
    end;

    procedure I_ShutDownNetwork;
    begin
    memfree(pointer(doomcom), SizeOf(doomcom_t));
    end;

    procedure I_NetCmd;
    begin
    if doomcom.command = CMD_SEND then
    netsend
    else if doomcom.command = CMD_GET then
    netget
    else
    I_Error('I_NetCmd(): Bad net cmd: %d', [doomcom.command]);
    end;

    end.
    [/pascal]
    Last edited by Jimmy Valavanis; 30-03-2012 at 03:42 PM.

  2. #2

    Winsock and recvfrom function

    Happy new year!

    I've fixed it!!!
    Last edited by Jimmy Valavanis; 30-03-2012 at 03:42 PM.

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
  •