![]() |
| ||
|
|
Новости |
Поиск |
FAQ |
Статьи |
Книги |
Новости VCL
| | Форумы ЧАТ |
Орешник |
|
| |||
| |||
« предыдущая ветвь | форум | следующая ветвь »
приложение Клиент-Сервер (winsock) [D5, D6, Win95/98]
Ricko © (2004-02-12 17:17:00)Никак не получается сделать приложение сочетающее в себе и клиента и сервера. Проблема в следующем: клиент коннектится, сервер: NewClient:=Accept(SockListen,nil,nil). Затем сервер посылает сообщение клиенту: send(NewClient,TextOut,len,0). Но почему то сам же его и принимает. Почему так происходит?
Rouse_ (2004-02-16 10:35:00) [1]http://book.itep.ru/7/sock_71.htm
http://gem.dpt.ustu.ru/InterNetBook/Contents.htm
Digitman (2004-02-16 10:24:00) [2]
> Может кто даст ссылки на subj
http://book.itep.ru, см.раздел "Winsock", там все расписано , ч.н., "на огурцах", влоть до графической циклограммы установки TCP/IP-соединения между кл. и серв. частью
штудируй от корки до корки !
Verg (2004-02-16 10:22:00) [3]Если интересует первоисточник:
MSDN:
When one of the nominated network events occurs on the specified socket s, the application's window hWnd receives message wMsg. The wParam parameter identifies the socket on which a network event has occurred. The low word of lParam specifies the network event that has occurred. The high word of lParam contains any error code.
Digitman (2004-02-16 10:19:00) [4]
> Вопрос был как сделать клиент-сервер в одном приложении
но это же вовсе не значит, что одни и те же переменные (например, хэндл некоего сокета) используются и той и другой логической частью приложения !
например, у тебя и кл.часть и серв.часть используют в разное время одну и ту же переменную Client
а ведь каждый из клиентов должен иметь свое собственное гнездо, создаваемое вызовом socket()
а сервер имеет в общем случае свои собственные 1 + N гнезд, где самое первое гнездо - слушающее (создаваемое таким же вызовом ф-ции socket), а прочие N гнезд - совершенно отдельные гнезда, по одному на каждого потенциально подключаемого клиента, создаваемые вызовом accept()
Verg (2004-02-16 10:16:00) [5]Когда ты обрабатываешь события сокета, то как ты отличаешь в связи с каким сокетом произошло это событие?
И вообще,
Старшее слово (word) lparam - это ошибка
Младшее слово lparam - это событие (FD_***)
А wparam - это собственно сокет.
Вот такого разбора сообщения я пока не вижу....
Polevi (2004-02-16 10:07:00) [6]для listen сокета достаточно FD_ACCEPT и FD_CLOSE
после accept необходимо вызвать WSAAsyncSelect для полученного хендла с FD_READ FD_WRITE FD_CLOSE
Ricko (2004-02-16 10:00:00) [7]Вопрос был как сделать клиент-сервер в одном приложении
Digitman (2004-02-16 09:52:00) [8]что за жуткая каша из клиентской и серверной части ?
у тебя программа функции чего выполняет ? клиента ? сервера ?
раздели код на два отдельных приложения : отдельно - приложение-клиент, отдельно - приложение-сервер
потом будет разговор
Ricko (2004-02-16 09:44:00) [9]По просьбам телезрителей привожу код:
program Mag;
uses windows,winsock;
const
WM_SOCKET = WM_USER+785;
var
WinClass : TWndClass;
hInst : HWND;
Handle : HWND;
hEditIn,hEditOut,hEditHost : HWND;
hBtnSent,hBtnConnect : HWND;
Msg : TMSG;
info : TWSADATA;
MyAddrTCP,ClientAddrTCP : TSockAddr;
SockList,client : integer;
TextIn : array[0..1023] of char;
HostName : array[0..127] of char;
// Отправление сообщения
procedure ClickBtnSent;
var
TextOut : array[0..127] of char;
len : integer;
begin
len:=GetWindowTextLength(hEditOut)+1;
GetWindowText(hEditOut,TextOut,len);
SetWindowText(hEditIn,TextOut);
send(Client,TextOut,len,0);
end;
// Коннектимся к серверу
procedure ClickBtnConnect;
begin
GetWindowText(hEditHost,HostName,SizeOf(HostName));
client:=socket(AF_INET,SOCK_STREAM,0);
ClientAddrTCP.sin_family:=AF_INET;
ClientAddrTCP.sin_port:=htons(1024);
ClientAddrTCP.sin_addr.S_addr:=d_addr(HostName);
connect(client,ClientAddrTCP,sizeOf(ClientAddrTCP))=0
end;
// Выход из программы
procedure ShutDownProg;
begin
ShutDown(SockList,SD_BOTH);
CloseSocket(SockList);
WSACleanup;
UnRegisterClass('Tas', hInst);
ExitProcess(hInst);
end;
function WindowProc(hwnd, msg, wparam, param:longint):longint;stdcall;
begin
Result:=DefWindowProc(hwnd,msg,wparam,lparam);
case Msg of
WM_SOCKET : begin
if lparam=FD_ACCEPT then
begin
client:=Accept(SockList,nil,nil);
SetWindowText(hEditIn,'Client connect');
end;
if lparam=FD_READ then
begin
recv(client,TextIn,SizeOf(TextIn),0)
SetWindowText(hEditIn,TextIn);
end;
if lparam=FD_CLOSE then
begin
ShutDown(client,1);
CloseSocket(client);
end;
end;
WM_DESTROY : ShutDownProg;
WM_COMMAND : begin
if lparam=hBtnSent then ClickBtnSent;
if lparam=hBtnConnect then ClickBtnConnect;
end;
end;
end;
begin
// Создание окна и назначение обработчика событий
// ...
// Запуск сервера
WSAStartup(MakeWord(2,0),info);
Socklist:=socket(AF_INET,SOCK_STREAM,0);
MyAddrTCP.sin_family:=AF_INET;
MyAddrTCP.sin_port:=htons(1024);
MyAddrTCP.sin_addr.S_addr:=htonl(INADDR_ANY);
bind(socklist,MyAddrTCP,sizeof(MyAddrTCP));
listen(socklist,SOMAXCONN);
WSAAsyncSelect(
socklist,Handle,WM_SOCKET,FD_ACCEPT+FD_READ+FD_CLOSE);
while(GetMessage(Msg,Handle,0,0))do
begin
TranslateMessage(Msg);
DispatchMessage(Msg);
end;
end.
Digitman (2004-02-16 09:27:00) [10]
> Может кто даст ссылки на subj
может кто-то в конце-концов код свой приведет здесь ?
Ricko (2004-02-16 09:17:00) [11]Может кто даст ссылки на subj
Polevi (2004-02-13 13:01:00) [12]где анализ результатов вызовов winsock ф-ий ?
Ricko (2004-02-13 09:02:00) [13]> Swimmer ©
> Нужно поменять настройки портов: Порт сервера и порт клиента в одном приложении должны быть разными.
Это аксиома?
Swimmer (2004-02-12 19:48:00) [14]Нужно поменять настройки портов: Порт сервера и порт клиента в одном приложении должны быть разными.
Verg (2004-02-12 17:35:00) [15]
> Ricko © (12.02.04 17:17)
> Почему так происходит?
Ошибка в программе.