{{notification.text}}

MirGames

18.03.07 16:58
0
Вобщем решил заюзать UDP и столкнулся с такими вот проблемками:
1. Когда создаю сокет:

Код
  Addr.sin_family := PF_INET;
  Addr.sin_addr.S_addr := INADDR_ANY;
  Addr.sin_port := HtoNS(Port);
  FillChar(Addr.sin_zero, SizeOf(Addr.sin_zero), 0);

  Bind(Result, Addr, SizeOf(Addr));


Так все гуд, а когда заменяю Bind на Connect, то ошибка SOCKET_ERROR:

Код
if Connect(Result, Addr, SizeOf(Addr)) = SOCKET_ERROR then
   <...>;


2. Пишу CloseSocket(sock); и программа виснет <_< ... sock: TSocket;

Помогите, плз.
#1
аксакал
18.03.07 21:51
0
Connect для UDP соединения требует биндинга на удалёной машине. И использовать его крайней не рекомендуется...
#2
18.03.07 22:43
0
Понятно... Переписал, но че-то не работает:
Код

unit Network;

interface
  uses WinSock;

type
  pHSocket = TSocket;

  TNet = object
    Net_init: boolean;
    function Init: boolean;
    procedure Shutdown;
    function CreateSocket(Port: integer): pHSocket;
    procedure CloseSocket(S: pHSocket);
    procedure Send(S: pHSocket; var Buf; IP: PChar; Port: Integer);
    function Get(S: pHSocket; var Buf): integer;
  end;

implementation

{ TNet }

procedure TNet.CloseSocket(S: pHSocket);
begin
  if not Net_init then
    exit;
  CloseSocket(S);
end;

function TNet.CreateSocket(Port: integer): pHSocket;
var
  Addr: TSockAddr;
  sock: pHSocket;
  i, flag: integer;
begin
  Result := -1;
  if not Net_init then
    exit;

  i := 1;
  flag := 1;

  sock := Socket(AF_INET, Sock_Dgram, IPProto_UDP);
  if (sock = INVALID_SOCKET) then
    exit;

  if ioctlsocket(sock, FIONBIO, flag) = -1 then
    exit;

  if setsockopt(sock, SOL_SOCKET, SO_BROADCAST, PChar(@i), SizeOf(i)) = -1 then
    exit;

  Addr.sin_family := PF_INET;
  Addr.sin_addr.S_addr := INADDR_ANY;
  Addr.sin_port := HtoNS(Port);
  FillChar(Addr.sin_zero, SizeOf(Addr.sin_zero), 0);

  if Bind(sock, Addr, SizeOf(Addr)) = SOCKET_ERROR then
    CloseSocket(Result);

  Result := sock;
end;

function TNet.Get(S: pHSocket; var Buf): integer;
var
  from: TSockAddr;
  fromlen: integer;
begin
  Result := -1;
  if not Net_init then
    exit;

  Result := RecvFrom(S, Buf, SizeOf(Buf), 0, from, fromlen);
end;

function TNet.Init: boolean;
var
  wsa_data: WSADATA;
begin
  Result := WSAStartup($0101, wsa_data) = 0;
  Net_init := Result;
end;

procedure TNet.Send(S: pHSocket; var Buf; IP: PChar; Port: Integer);
var
  AddrTo: TSockAddr;
begin
  if not Net_init then
    exit;
  AddrTo.sin_family := PF_INET;
  if IP <> nil then
    AddrTo.sin_addr.S_addr := Inet_Addr(IP)
  else
    AddrTo.sin_addr.S_addr := INADDR_BROADCAST;
  AddrTo.sin_port := HtoNS(Port);
  FillChar(AddrTo.sin_zero, SizeOf(AddrTo.sin_zero), 0);

  SendTo(S, Buf, SizeOf(Buf), 0, AddrTo, SizeOf(TSockAddr));
end;

procedure TNet.Shutdown;
begin
  if not Net_init then
    exit;
  WSACleanup;
end;

end.


Код

unit Unit1;

interface

uses
  Windows, Messages, SysUtils, Variants, Classes, Graphics, Controls, Forms,
  Dialogs, StdCtrls, Network, ExtCtrls, WinSock;

type
  TForm1 = class(TForm)
    Memo1: TMemo;
    Edit1: TEdit;
    Button1: TButton;
    Timer1: TTimer;
    procedure FormCreate(Sender: TObject);
    procedure FormDestroy(Sender: TObject);
    procedure Button1Click(Sender: TObject);
    procedure Timer1Timer(Sender: TObject);
  private
    { Private declarations }
  public
    { Public declarations }
  end;

var
  Form1: TForm1;
  Net: TNet;
  MySocket: pHSocket;

implementation

{$R *.dfm}

procedure TForm1.FormCreate(Sender: TObject);
begin
  if not Net.Init then
  begin
    ShowMessage('Невозможно создать соединение');
    exit;
  end;
  MySocket := Net.CreateSocket(3320);
end;

procedure TForm1.FormDestroy(Sender: TObject);
begin
//  Net.CloseSocket(MySocket);
  Net.Shutdown;
end;

procedure TForm1.Button1Click(Sender: TObject);
var
  buf: string;
begin
  buf := Edit1.Text;
  Net.Send(MySocket, buf, nil, 3320);
end;

procedure TForm1.Timer1Timer(Sender: TObject);
var
  buf: string;
begin
  if Net.Get(MySocket, buf) > 0 then
    Memo1.Lines.Add(buf);
end;

end.


Сделал так и ничего не приходит/не отправляет... В чем косяк? <_<
#3
mov, просто mov
18.03.07 23:53
0
beisik
Код

procedure TNet.CloseSocket(S: pHSocket);
begin
  if not Net_init then
    exit;
  CloseSocket(S);
end;

вот почему он у тя виснет вызывает сам себя :)
#4
аксакал
19.03.07 00:00
0
1) Eсли при создании сокета забиндить его не удалось - возвращается ложный (уже закрытый) сокет. Никаких дальнейших проверок его корректности не заметил :)

2) Net.Send(MySocket, buf[1], nil, 3320);
3) SizeOf(Buf) = 0. Т.е. твой Send ничего не отправляет, передавай размер отправляемых данных в метод Send )
4)
Код
procedure TNet.CloseSocket(S: pHSocket);
begin
  if Net_init then
    WinSock.closesocket(S);
end;
Отредактировано: 19.03.07 00:02
#5
19.03.07 02:11
0
Пасибо вам MegaI2 и XProger :)
#6
19.03.07 03:45
0
Не знаю че за фигня, но все равно не пошло... Я в шоке! :blink: Решил проверить - мож сеть глючит - запустил l_net (http://XProger.mirgames.ru/files/lib/l_net.rar) и... нифига не работает! XProger, признавайся это фигли твой пример не работает даже?! <_<
network.rar
#7
аксакал
19.03.07 04:16
0
beisik
По всем проблемам обращаться к своим фаерволам, провайдерам и прочим инстанциям :)
#8
mov, просто mov
19.03.07 15:17
0
beisik
чёто я покапался покопался:)
и получилось что он у меня начал посылать данные даже на свой IP :)
#9
Почётный лектор
19.03.07 19:19
0
Цитата(MegaI2 @ Сегодня, 11:17)
[snapback]52452[/snapback]
получилось что он у меня начал посылать данные даже на свой IP

почему бы и нет? Все так и должно быть
#10
mov, просто mov
19.03.07 20:24
0
Цитата
Все так и должно быть

он раньше не пасылал :)
#11
23.03.07 03:53
0
Вот решил забить на UDP и заюзать TCP... Сделал простенькую проггу, но вот беда - на компе работает, а в интернете (с другим юзером) - нет... подскажите в чем проблемма)
вот код:
сервер
Код
program Server;

{$APPTYPE CONSOLE}

uses
  WinSock;

const
  MSG_SIZE = 128;

var
  app_true: boolean = true;

  wsa_data: WSAData;
  sock: TSocket;
  Addr: TSockAddr;

  n_l: integer;
  str_: string;

  new_conn: TSocket;
  new_ca: TSockAddr;
  new_len: integer;
  i, c: integer;
  msg_len: integer;
  buff: array[0..MSG_SIZE-1] of Char;
begin
  i := 0;
  WriteLn('Initialization...');
  if WSAStartup($0101, wsa_data) <> 0 then
  begin
    app_true := false;
    exit;
  end;
  WriteLn('OK');

  WriteLn('Create socket...');
  sock := socket(AF_INET, SOCK_STREAM, IPPROTO_TCP);
  if sock = INVALID_SOCKET then
  begin
    app_true := false;
    exit;
  end;
  WriteLn('OK');

  WriteLn('Bind socket...');
  Addr.sin_family := AF_INET;
  Addr.sin_addr.S_addr := Inet_addr('127.0.0.1');
  Addr.sin_port := HtoNS(65535);
  FillChar(Addr.sin_zero, SizeOf(Addr.sin_zero), 0);
  if bind(sock, Addr, SizeOf(Addr)) = SOCKET_ERROR then
  begin
    app_true := false;
    exit;
  end;
  WriteLn('OK');

  WriteLn('Get host info...');
  FillChar(Addr, SizeOf(Addr), 0);
  n_l := SizeOf(Addr);
  getsockname(sock, Addr, n_l);
  WriteLn('Server IP: ' + inet_ntoa(Addr.sin_addr));
  Str(HtoNS(Addr.sin_port), str_);
  WriteLn('Server port: ' + str_);

  WriteLn('Listening...');
  if listen(sock, SOMAXCONN) = -1 then
  begin
    app_true := false;
    exit;
  end;

  while i < SOMAXCONN do
  begin
    FillChar(new_ca, SizeOf(new_ca), 0);
    new_len := SizeOf(new_ca);
    new_conn := accept(sock, @new_ca, @new_len);
    Str(i, str_);
    if new_conn = -1 then
    begin
      WriteLn('Accept failed on ' + str_);
      exit;
    end
    else
    begin
      WriteLn('New Client... Num ' + str_);
      WriteLn('Client IP: ' + inet_ntoa(new_ca.sin_addr));
      Str(ntohs(new_ca.sin_port), str_);
      WriteLn('Client Port: ' + str_);
      msg_len := recv(new_conn, buff, MSG_SIZE, 0);
      if (msg_len = SOCKET_ERROR) or (msg_len = 0) then
        exit;
      for c := 0 to msg_len-1 do
        str_ := str_ + buff[c];
      WriteLn(str_);
      Closesocket(new_conn);
    end;
    i := i + 1;
  end;

  while app_true do
end.

клиент
Код

program Client;

{$APPTYPE CONSOLE}

uses
  WinSock;

const
  MSG_SIZE = 128;

var
  app_true: boolean = true;

  wsa_data: WSAData;
  sock: TSocket;
  Addr: TSockAddr;
  buff: array[0..MSG_SIZE-1] of Char;
begin
  buff[0] := 'H';
  buff[1] := 'E';
  buff[2] := 'L';
  buff[3] := 'L';
  buff[4] := 'O';
  WriteLn('Init...');
  if WSAStartup($0101, wsa_data) <> 0 then
  begin
    app_true := false;
    exit;
  end;
  WriteLn('OK');

  WriteLn('Create socket...');
  sock := socket(AF_INET, SOCK_STREAM, IPPROTO_TCP);
  if sock = INVALID_SOCKET then
  begin
    app_true := false;
    exit;
  end;
  WriteLn('OK');

  WriteLn('Connect with host...');
  addr.sin_family := AF_INET;
  addr.sin_addr.S_addr := Inet_Addr('127.0.0.1');
  addr.sin_port := HtoNs(65535);
  FillChar(Addr.sin_zero, SizeOf(Addr.sin_zero), 0);
  if Connect(sock, addr, SizeOf(addr)) = SOCKET_ERROR then
  begin
    app_true := false;
    exit;
  end;
  WriteLn('OK');

  if send(sock, buff, MSG_SIZE, 0) = SOCKET_ERROR then
  begin
    app_true := false;
    exit;
  end;
  WriteLn('OK');
  if closesocket(sock) = SOCKET_ERROR then
  begin
    app_true := false;
    exit;
  end;
  WriteLn('OK');
  WriteLn('Close connection...');
  if WSACleanup <> 0 then
  begin
    app_true := false;
    exit;
  end;
  WriteLn('OK');  
  while app_true do
end.
#{{post.Index}}
{{post.Author.Login}}
{{post.CreatedDate | date:'dd.MM.yy HH:mm'}}
{{post.VotesRating}}
Отредактировано: {{post.UpdatedDate | date:'dd.MM.yy HH:mm'}}