· Начало · Статистика · Поиск · FAQ · Правила · Установки · Язык · Выход · WASM.RU · Noir.Ru ·

 WASM Phorum —› WASM.NETWORKS —› WEB server на парадигме BSD soket'ов

Посл.отвђт Сообщенiе


Дата: Авг 23, 2004 20:35:19 · Поправил: AEX CHECKER

Здравствуйте.
Начал писать маленький сервер, используя парадигму BSD сокетов. И натолкнулся на непонятные трудности. Ниже приведенный сорс - работает(сильно накоментировано но это для себя тольно начинаю ;)).
НО меня волнует то что количество дескрипторов у сервера прибавляется (Task Manadger показывает) при каждом обновлении страницы в броузере (я думаю это дескрипторы сокетов для send) чего не должно быть.

Вопрос 1: правильно ли я выключаю и закрываю сокеты?
Вопрос 2: если я правильно зарываю сокеты то в чем проблема?
.486
.MODEL	 FLAT,STDCALL
OPTION	 CASEMAP:NONE

include 	htaserver.inc

NEW		equ 1
OLD		equ 0
prsize		equ 53333
rcvsize		equ 1333
hstsize		equ 33


;:::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::  ::::::::::
;	D A T A
;:::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::  ::::::::::
.DATA
inadrlen	dd SIZEOF sockaddr_in
STAT		dd OLD
IndexNEW	db '<html>',13,10
		db '<head>',13,10
		db '<meta http-equiv="Content-Language" content="en-us">',13,10
		db '<meta http-equiv="Content-Type" content="text/html; charset=windows-1252">',13,10
		db '<title>NEW :: server</title>',13,10
		db '</head>',13,10
		db '<body>',13,10
		db '<p><font color="#0000FF"><h1>NEW server</h1></font></p>',13,10
		db '</body>',13,10
		db '</html>',0
szIndexNEW	equ $-IndexNEW

IndexOLD	db '<html>',13,10
		db '<head>',13,10
		db '<meta http-equiv="Content-Language" content="en-us">',13,10
		db '<meta http-equiv="Content-Type" content="text/html; charset=windows-1252">',13,10
		db '<title>OLD :: server</title>',13,10
		db '</head>',13,10
		db '<body>',13,10
		db '<p><font color="#FF0000"><h1>OLD server</h1></font></p>',13,10
		db '</body>',13,10
		db '</html>',0
szIndexOLD	equ  $-IndexOLD


;:::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::  ::::::::::
;	D A T A ?
;:::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::  ::::::::::
.DATA?
WSD 		WSADATA 	<>
SH		HWND		?
SA		sockaddr_in	<>
inSH		HWND		?
inSA		sockaddr_in	<>
buf		dd		?
threadid	dd		?
StrBuf		db		1024 dup(?)


;:::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::  ::::::::::
;	C O D E
;:::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::  ::::::::::
.CODE

start:                                  ; for comment position 40
            mov WSD.iMaxSockets,1
            
            push OFFSET (WSD)           ; [out] pointer to the WSADATA structure
            push 101h                   ; [in] highest version of Socket
            call WSAStartup 
            
            push IPPROTO_IP             ; [in] protocol specification
            push SOCK_STREAM            ; [in] type specification
            push AF_INET                ; [in] family specification
            call socket
            
            mov SH,eax                  ; saved descriptor main_socket
            
            mov SA.sin_addr,NULL        ; structure sockaddr_in
            mov ah,80
            mov al,00
            mov SA.sin_port,ax          ; http port = 80
            mov SA.sin_family,AF_INET   ; family specification
            
            push SIZEOF SA              ; [in] length of the value
            push OFFSET (SA)            ; [in] pointer to the sockaddr_in structure
            push SH                     ; [in] descriptor main_socket
            call bind
            
            push SOMAXCONN              ; [in] maximum length of the queue of pending connections
            push SH                     ; [in] descriptor main_socket
            call listen

accloop:
            push OFFSET (inadrlen)      ; [out] pointer to length of sockaddr_in
            push OFFSET (inSA)          ; [out] pointer to sockaddr_in for main_socket 
            push SH                     ; [in] descriptor main_socket 
            call accept
            
            cmp eax,-1
            jz short accloop            ; if (!OK) goto accloop 
            mov inSH,eax                ; else inSH=child_socket
            
question_answer:

            push NULL                   ; [in] flag specifying
            push 1024                   ; [in] length of buf
            push OFFSET (StrBuf)        ; [out] buffer for the incoming data
            push inSH                   ; [in] descriptor child_socket
            call recv
            
            cmp STAT,0
            jz pageOLD
            
pageNEW:
            mov STAT,OLD                ; if (NEW) OLD
            
            push MSG_DONTROUTE          ; specifies that the data should not be subject to routing
            push SIZEOF szIndexNEW      ; [in] length of the data
            push OFFSET (IndexNEW)      ; [in] buffer containing the data to be transmitted
            push inSH                   ; [in] descriptor child_socket
            call send
            
            push 2                      ; [in] describes what types of operation will no longer be allowed
            push inSH                   ; [in] descriptor child_socket
            call shutdown
            
            push inSH                   ; [in] descriptor child_socket
            call closesocket
            
            jmp accloop
            
pageOLD:
            mov STAT,NEW                ; if (OLD) NEW
            
            push MSG_DONTROUTE          ; specifies that the data should not be subject to routing
            push SIZEOF szIndexOLD      ; [in] length of the data
            push OFFSET (IndexOLD)      ; [in] buffer containing the data to be transmitted
            push inSH                   ; [in] descriptor child_socket
            call send
            
            push inSH                   ; [in] descriptor child_socket
            call closesocket
            
            jmp accloop

end start


Широкова-то вышло :))}


Дата: Авг 24, 2004 20:48:44

по повуду закрытия если надо зактыть сокет и чтоб потом он не висел пока ядро его не закроет делай так:

void __fastcall set_linger(SOCKET as) {
struct linger sLinger={1,0};
setsockopt(as,SOL_SOCKET,SO_LINGER,(const char *)sLinger,sizeof(sLinger) );
}
з.ы. только где я читал что если так делать у клиента , то если несколько коннектов к серверу моут отвалиться соединения.


Дата: Авг 26, 2004 01:50:30 · Поправил: AEX CHECKER

khv_test

Посмотрел на свой фаервол И О, БОЖЕ!!! Оказывается лишние соки в режиме TIME_WAIT . Внизу вариант кода как с этим справляется апач. Он мне не нравится – зато появилась мысля как это иcправить … за день или два покажу что вышло. Заходи :))
static void close_unused_listeners(void)
{
    listen_rec *or, *next;

    for (or = old_listeners; or; or = next) {
	next = or->next;
	if (!or->used)
	    closesocket(or->fd);
	free(or);
    }
    old_listeners = NULL;
}