1、如何將select的option全部回傳伺服器
在提交之前執行一下for循環,先把ListBox2的所有項的selected設置為true,然後再執行submit事件,這樣就可以把所有ListBox2的項都提交到伺服器端了
2、伺服器端,在WSAEventSelect模型下,怎麼判斷收到的FD
------解決方案--------------------
WSAWaitForMultipleEvents
------解決方案--------------------
TCP客戶端用WSAWaitForMultipleEvents等待所有數據連接的FD_READ、FD_CLOSE
TCP伺服器端用WSAWaitForMultipleEvents等待監聽的FD_ACCEPT和數據連接的FD_READ、FD_CLOSE
不管是客戶端還是伺服器端,每建立一個SOCKET就WSACreateEvent一個EVENT並WSAEventSelect,在WSAWaitForMultipleEvents裡面等這些EVENT,EVENT與SOCKET一一對應,更具WSAWaitForMultipleEvents的返回值來確定是哪個SOCKET
------解決方案--------------------
你要支持更多的客戶端就用完成埠。。
------解決方案--------------------
WSAWaitForMultipleEvents對每64個Event分組進行查詢的方式達到支持> 64客戶端的支持
缺點就是效率比完成埠低
3、如何將select模型改為非同步選擇模型
非同步選擇(WSAAsyncSelect)模型是一個有用的非同步 I/O 模型。利用這個模型,應用程序可在一個套接字上,
接收以 Windows 消息為基礎的網路事件通知。具體的做法是在建好一個套接字後,調用WSAAsyncSelect函數。
該模型的核心即是WSAAsyncSelect函數。
█ 要想使用 WSAAsyncSelect 模型,在應用程序中,首先必須用CreateWindow函數創建一個窗口,再為該窗口提供一個窗口常式函數(WinProc)。
█ WSAAsyncSelect 的函數原型如下:
[cpp] view plain copy
int WSAAsyncSelect(
__in SOCKET s,
__in HWND hWnd,
__in unsigned int wMsg,
__in long lEvent
);
● s 參數指定的是我們感興趣的那個套接字。
● hWnd 參數指定一個窗口句柄,它對應於網路事件發生之後,想要收到通知消息的那個窗口。
● wMsg 參數指定在發生網路事件時,打算接收的消息。該消息會投遞到由hWnd窗口句柄指定的那個窗口。
(通常,應用程序需要將這個消息設為比Windows的WM_USER大的一個值,避免網路窗口消息與系統預定義的標准窗口消息發生混淆與沖突)
● lEvent 參數指定一個位掩碼,對應於一系列網路事件的組合,大多數應用程序通常感興趣的網路事件類型包括:
FD_READ、FD_WRITE、FD_ACCEPT、FD_CONNECT、FD_CLOSE。當然,到底使用FD_ACCEPT,還是使用FD_CONNECT類型,
要取決於應用程序的身份是客戶端,還是伺服器。如應用程序同時對多個網路事件有興趣,只需對各種類型執行一次簡單的按位OR(或)運算,
然後將它們分配給lEvent就可以了,例如:
WSAAsyncSeltct(s, hwnd, WM_SOCKET, FD_CONNECT | FD_READ | FD_WRITE | FD_CLOSE);
解釋說明:我們的應用程序以後便可在套接字s上,接收到有關連接、發送、接收以及套接字關閉這一系列網路事件的通知。
█ 注意 ①:
多個事件務必在套接字上一次注冊!
另外還要注意的是,一旦在某個套接字上允許了事件通知,那麼以後除非明確調用closesocket命令,
或者由應用程序針對那個套接字調用了WSAAsyncSelect,從而更改了注冊的網路事件類型,否則的話,
事件通知會永遠有效!若將lEvent參數設為0,效果相當於停止在套接字上進行的所有網路事件通知。
█ 注意 ②:
若應用程序針對一個套接字調用了WSAAsyncSelect,那麼套接字的模式會從「鎖定」變成「非鎖定」。
這樣一來,如果調用了像WSARecv這樣的Winsock函數,但當時卻並沒有數據可用,那麼必然會造成調用的失敗,並返回WSAEWOULDBLOCK錯誤。
為防止這一點,應用程序應依賴於由WSAAsyncSelect的uMsg參數指定的用戶自定義窗口消息,來判斷網路事件類型何時在套接字上發生;而不應盲目地進行調用。
FD_READ 應用程序想要接收有關是否可讀的通知,以便讀入數據
FD_WRITE 應用程序想要接收有關是否可寫的通知,以便寫入數據
FD_ACCEPT 應用程序想接收與進入連接有關的通知
FD_CONNECT 應用程序想接收與一次連接完成的通知
FD_CLOSE 應用程序想接收與套接字關閉的通知
█ 應用程序在一個套接字上成功調用了WSAAsyncSelect之後,會在與hWnd窗口句柄對應的窗口常式中,以Windows消息的形式,接收網路事件通知。
窗口常式通常定義如下:
[cpp] view plain copy
LRESULT CALLBACK WindowProc(
HWND hwnd,
UINT uMsg,
WPARAM wParam,
LPARAM lParam
);
● hWnd 參數指定一個窗口的句柄,對窗口常式的調用正是由那個窗口發出的。
● uMsg 參數指定需要對哪些消息進行處理。這里我們感興趣的是WSAAsyncSelect調用中定義的消息。
● wParam 參數指定在其上面發生了一個網路事件的套接字。假若同時為這個窗口常式分配了多個套接字,這個參數的重要性便顯示出來了。
● lParam參數中,包含了兩方面重要的信息。其中, lParam的低字(低位字)指定了已經發生的網路事件,而lParam的高字(高位字)包含了可能出現的任何錯誤代碼。
█ 步驟:網路事件消息抵達一個窗口常式後,應用程序首先應檢查lParam的高字位,以判斷是否在網路錯誤。
這里有一個特殊的宏: WSAGETSELECTERROR,可用它返回高字位包含的錯誤信息。
若應用程序發現套接字上沒有產生任何錯誤,接著便應調查到底是哪個網路事件類型,具體的做法便是讀取lParam低字位的內容。
此時可使用另一個特殊的宏:WSAGETSELECTEVENT,用它返回lParam的低字部分。
█ 注意 ③:應用程序如何對 FD_WRITE 事件通知進行處理。
只有在三種條件下,才會發出 FD_WRITE 通知:
■ 使用 connect 或 WSAConnect,一個套接字首次建立了連接。
■ 使用 accept 或 WSAAccept,套接字被接受以後。
■ 若 send、WSASend、sendto 或 WSASendTo 操作失敗,返回了 WSAEWOULDBLOCK 錯誤,而且緩沖區的空間變得可用。
因此,作為一個應用程序,自收到首條 FD_WRITE 消息開始,便應認為自己必然能在一個套接字上發出數據,
直至一個send、WSASend、sendto 或 WSASendTo 返回套接字錯誤 WSAEWOULDBLOCK。
經過了這樣的失敗以後,要再用另一條 FD_WRITE 通知應用程序再次發送數據。
用例:
[cpp] view plain copy
WSAAsyncSelect(pThis->m_SockListen, pThis->GetSafeHwnd(), WM_SOCKET, FD_ACCEPT | FD_CLOSE);//WM_SOCKET為自定義消息#define WM_SOCKET WM_USER+100
[cpp] view plain copy
//override窗口過程函數
LRESULT CServerDlg::WindowProc(UINT message, WPARAM wParam, LPARAM lParam)
{
switch(message)
{
case WM_SYSCOMMAND:
if (wParam == SC_CLOSE) {
closesocket(m_SockClient);
closesocket(m_SockListen);
WSACleanup();
}
break;
case WM_SOCKET:
if (WSAGETSELECTERROR(lParam)) {
--m_ClientNums;
closesocket(wParam);
break;
}
switch(WSAGETSELECTEVENT(lParam))
{
case FD_ACCEPT:
{
if (m_ClientNums >= 1) {
break;
}
m_SockClient = accept(wParam, NULL, NULL);
WSAAsyncSelect(m_SockClient, m_hWnd, WM_SOCKET, FD_READ|FD_WRITE|FD_CLOSE);
++m_ClientNums;
break;
}
case FD_READ:
{
TCHAR szBuf[MAX_BUF_SIZE] = {0};
recv(wParam, (char *)szBuf, MAX_BUF_SIZE, 0);
ShowMsg(szBuf);
break;
}
case FD_WRITE:
wParam = wParam;
break;
case FD_CLOSE:
--m_ClientNums;
closesocket(wParam);
break;
}
default:break;
}
return CDialog::WindowProc(message, wParam, lParam);
}
4、如何實現「select * from "伺服器名".資料庫名.表名」
樓主,不是吧,你怎麼會想到這樣一個設計方案啊?不只是在SQL中,我想在任何一個資料庫都不可能會有這樣的功能,你難道是要用資料庫連接資料庫?這是沒有意思的事情.即使有這種需要也不是這樣實現的,一般都是通過其它的程序中的功能來實現的.
5、sql server 中如何select不同伺服器的資料庫
如已經建立連接伺服器,直接select * from 伺服器ip.資料庫.dbo.表 就可以訪問
否則可以採用:
SELECT *
FROM OPENDATASOURCE(
'SQLOLEDB',
'Data Source=ServerName;User ID=MyUID;Password=MyPass'
).pubs.dbo.表, OPENDATASOURCE(
'SQLOLEDB',
'Data Source=另一台pcServerName;UserID=另UID;Password=另Pass'
).pubs.dbo.表
----
如有不明白F1查OPENDATASOURCE
6、windows select模型 和linux的區別
1、免費與收費 在中國,windows和linux都是免費的,至少對個人用戶是如此,如果那天國內windows真的嚴打盜版了,那linux的春天就到了!但現在linux依然是任重道遠,前路漫漫。 2、軟體與支持 windows下可以運行絕大部分軟體、玩99.999%的游戲、...
7、ace acceptor用的是select模型嗎
|我們先看一個服務小例子,並比較Reactor框架
#include <iostream>
#include "ace/auto_ptr.h"
#include "ace/log_msg.h"
#include "ace/inet_addr.h"
#include "ace/sock_acceptor.h"
#include "ace/reactor.h"
#include "ace/acceptor.h"
#include "ace/Connector.h"
#include "ace/Reactor_Notification_Strategy.h"
#include "ace/Select_Reactor.h"
#include "ace/Singleton.h"
#include "ace/svc_handler.h"
#include "ace/Message_Block.h"
#include "ace/Message_Queue.h"
#include "ace/SOCK_Stream.h"
#include "ace/Null_Mutex.h"
#include "ace/Null_Condition.h"
using namespace std;
//服務客戶
class ClientService:public ACE_Svc_Handler<ACE_SOCK_STREAM,ACE_NULL_SYNCH>
{
public:
int open(void *p);
virtual int handle_input(ACE_HANDLE fd=ACE_INVALID_HANDLE);
virtual int handle_output(ACE_HANDLE fd=ACE_INVALID_HANDLE);
virtual int handle_close(ACE_HANDLE handle,ACE_Reactor_Mask close_mask);
protected:
ACE_SOCK_Stream sock_;
ACE_Message_Queue<ACE_NULL_SYNCH> output_queue_;
};
int ClientService::open(void *p)
{
if(ACE_Svc_Handler::open(p)==-1)
return -1;
ACE_TCHAR peer_name[512];
ACE_INET_Addr peer_addr;
if(this->peer().get_remote_addr(peer_addr)==0&&peer_addr.addr_to_string(peer_name,512)==0)
cout<<" connection from "<<peer_name<<endl;
return 0;
}
int ClientService::handle_input(ACE_HANDLE)
{
const size_t INPUT_SIZE=4096;
char buffer[INPUT_SIZE];
ssize_t recv_cnt,send_cnt;
if((recv_cnt=this->peer().recv(buffer,sizeof(buffer)))<=0)
{
ACE_DEBUG((LM_DEBUG,ACE_TEXT("(%P|%t) connection closed/n")));
return -1;
}
send_cnt=this->peer().send(buffer,ACE_static_cast(size_t,recv_cnt));
if(send_cnt==recv_cnt)
return 0;
if(send_cnt==-1&&ACE_OS::last_error()!=EWOULDBLOCK)
ACE_ERROR_RETURN((LM_ERROR,ACE_TEXT("%P|%t) %p/n"),ACE_TEXT("send")),0);
if(send_cnt==-1)
send_cnt=0;
ACE_Message_Block *mb;
size_t remaining=ACE_static_cast(size_t,(recv_cnt-send_cnt));
ACE_NEW_RETURN(mb,ACE_Message_Block(&buffer[send_cnt],remaining),-1);
int output_off=this->msg_queue()->is_empty();
ACE_Time_Value nowait(ACE_OS::gettimeofday());
if(this->putq(mb,&nowait)==-1)
{
ACE_ERROR((LM_ERROR,ACE_TEXT("(%P|%t)%P;d
不同Reactor框架,此框架無需寫ClientAcceptor類,即無需設置acceptor對象的ACE_Reactor實例,只需typedef
typedef ACE_Acceptor<ClientService,ACE_SOCK_ACCEPTOR> ClientAcceptor;
我們繼續考察ClientService類
class ClientService:public ACE_Svc_Handler<ACE_SOCK_STREAM,ACE_NULL_SYNCH>
ACE_Svc_Handler允許你指定流類型和加鎖類型,與ACE_Acceptor一樣,ACE_Svc_Handler需要使用流的地址trait,所以我們使用了ACE_SOCK_STREAM宏,使這些代碼在支持或不支持模板trait類型的系統上都能編譯
之所以要加鎖類型,是因為ACE_Svc_Handler是派生自ACE_Task的,後者含有一個ACE_Message_Queue成員,你必須為這個成員提供同步類型。
在此我們不會使用ACE_Task提供的線程能力,但我們要使用繼承而得的ACE_Message_Queue成員,所以我們移除了先前例子的ACE_Message_Queue成員。
另外,我們只使用一個線程,所以用ACE_NULL_SYNCH
注意:ACE_Svc_Handler按照我們通常所需的方式實現了get()_handle()方法,所以此方法也不見了
接著,再看handle_input(ACE_HANDLE)方法,與前一個版本不同的是:
1.我們使用ACE_Svc_Handler::peer()方法是訪問底層的ACE_SOCK_Stream
2.我們通過繼承的ACE_Task::msg_queue()方法訪問繼承的ACE_Message_Queue
3.為了把數據塊放入隊列中,我們可以繼承而得的ACE_Task::putq()方法。同樣,我們新的handle_output也類似的,但他利用了繼承而得的方法
最後,默認的handle_close()方法會移除所有的反應器登記信息,取消所有的定時器,並刪除該處理器
ACE_Svc_Handler的使用極大地簡化了我們的服務處理器,使得我們能完全專注於需要的解決的問題,而不需要為所有那些連接管理問題而分心
接著,我們再看ACE_Connector
#include <iostream>
#include "ace/reactor.h"
#include "ace/inet_addr.h"
#include "ace/sock_stream.h"
#include "ace/sock_connector.h"
#include "ace/connector.h"
#include "ace/svc_handler.h"
#include "ace/reactor_notification_strategy.h"
#include <conio.h>
using namespace std;
typedef ACE_Svc_Handler<ACE_SOCK_STREAM,ACE_NULL_SYNCH> super;
class Client:public ACE_Svc_Handler<ACE_SOCK_STREAM,ACE_NULL_SYNCH>
{
public:
Client():notifier_(0,this,ACE_Event_Handler::WRITE_MASK)
{
}
virtual int open(void *p=0);
virtual int handle_input(ACE_HANDLE fd=ACE_INVALID_HANDLE);
virtual int handle_output(ACE_HANDLE fd=ACE_INVALID_HANDLE);
virtual int handle_timeout(const ACE_Time_Value ¤t_time,const void *act=0);
private:
enum{ITERATIONS=5};
int iterations_;
ACE_Reactor_Notification_Strategy notifier_;
};
int Client::open(void *p)
{
ACE_Time_Value iter_delay(2);
if(ACE_Svc_Handler::open(p)==-1)
return -1;
this->notifier_.reactor(this->reactor());
this->msg_queue()->notification_strategy(this->notifier_);
return this->reactor()->schele_timer(this,0,ACE_Time_Value::zero,iter_delay);
}
int Client::handle_input(ACE_HANDLE)
{
char buf[64];
ssize_t recv_cnt=this->peer().recv(buf,sizeof(buf)-1);
if(recv_cnt>0)
{
}
if(recv_cnt==0||ACE_OS::last_error()!=EWOULDBLOCK)
從程序中我們看到有一個新類,ACE_Reactor_Notification_Strategy是一個策略類,實現了Strategy模式,它允許你定製另一個類的行為,且無需改變受影響的類
在例子中也可以看到構造的時候先初始化了notifier_對象,設置正確的ACE_Reactor指針,目的是通過ACE_Reactor_Notification_Strategy這樣的對象使ACE_Message_Queue策略化。如果ACE_Message_Queue擁有一個策略對象,無論何時有ACE_Message_Block對象進入隊列,ACE_Message_Queue都會調用該策略對象的notify()方法。因為我們已經設置了notifier_,他會在Client的反應器上發出notify()調用,把一個通知放入隊列,通知的目標是我們的client對象的handle_output()方法。要把ACE_Message_Queue的入隊操作結合進反應器的事件循環
handle_timeout方法:如果我們把預定數目的串發給伺服器,就是用close_writer()方法關閉我們這一端的TCP/IP socket。
注意,對於我們想要發往伺服器的每一個串,我們都把它插入一個ACE_Message_Block,並把這個塊放入隊列,這將使消息隊列用notifier_對象把通知放入反應器的隊列。當反應器處理該通知時,他會調用我們的handle_output方法,然後我們從隊列中取出數據,直到隊列變空。
在handle_output方法中,有cancel_wakeup()和schele_wakeup(),前者是從這個處理器的反應器登記信息中移除指定的掩碼位,而schele_wakeup()則增加指定的掩碼。也就是說不會造成handle_close()被調用。因此,這一次也無需實現handle_close(),以專門處理被取消的WRITE掩碼,我們復用了ACE_Svc_Handler的默認handle_close()方法,所以無需編寫代碼
8、select 模型中伺服器端 可寫代碼為什麼放到可讀里
非同步選擇(WSAAsyncSelect)模型是一個有用的非同步 I/O 模型。利用這個模型,應用程序可在一個套接字上,
接收以 Windows 消息為基礎的網路事件通知。具體的做法是在建好一個套接字後,調用WSAAsyncSelect函數。
該模型的核心即是WSAAsyncSelect函數。
█ 要想使用 WSAAsyncSelect 模型,在應用程序中,首先必須用CreateWindow函數創建一個窗口,再為該窗口提供一個窗口常式函數(WinProc)。
9、select函數怎麼提高了伺服器的性能
方法如下。 1.創建一個監聽TCP套接字並捆綁伺服器的眾所周知的埠,設置SO_REUSEADDR套接字選項以防止該埠上已有連接存在。 2.還創建一個UDP套接字並捆綁與TCP套接字相同的埠。這里無需在調用bind之前設置SO_REUSEADDR套接字選項,