導航:首頁 > 源碼編譯 > xsocket源碼

xsocket源碼

發布時間:2022-01-13 19:32:43

1. VB 如何用:socket 發送數據

1、首先看控制項區有無串口控制項,表明串口控制項並未被啟用,選擇工程→部件→Micosoft comm Control6.0選項,點擊應用,即可添加串口控制項。

2. 如何用mina的ProtocolDecoder來解析websocket的消息

MINA,Grizzly[grizzly-nio-framework],xSocket都是基於 java nio的 server framework.

這里的性能缺陷的焦點是指當一條channel上的SelectionKey.OP_READ ready時,1.是由select thread讀完數據之後再分發給應用程序的handler,2.還是直接就分發,由handler thread來負責讀數據和handle.

mina,xsocket是1. grizzly-nio-framework是2.

盡管讀channel buffer中bytes是很快的,但是如果我們放大,當連接channel達到上萬數量級,甚至更多,這種延遲響應的效果將會愈加明顯.

MINA:

for all selectedKeys

{

read data then fireMessageReceived.

}

xSocket:

for all selectedKeys

{

read data ,append it to readQueue then performOnData.

}

其中mina在fireMessageReceived時沒有使用threadpool來分發,所以需要應用程序在handler.messageReceived中再分發.而xsocket的performOnData默認是分發給threadpool[WorkerPool],WorkerPool雖然解決了線程池中的線程不能充到最大的問題[跟tomcat6的做法一樣],但是它的調度機制依然缺乏靈活性.

Grizzly:

for all selectedKeys

{

[NIOContext---filterChain.execute--->our filter.execute]<------run In DefaultThreadPool

}

grizzly的DefaultThreadPool幾乎重寫了java util concurrent threadpool,並使用自己的LinkedTransferQueue,但同樣缺乏靈活的池中線程的調度機制.

下面分別是MINA,xSocket,Grizzly的源碼分析:

Apache MINA (mina-2.0.0-M6源碼為例):

我們使用mina nio tcp最常用的樣例如下:

NioSocketAcceptor acceptor = new NioSocketAcceptor(/*NioProcessorPool's size*/);
DefaultIoFilterChainBuilder chain = acceptor.getFilterChain();

//chain.addLast("codec", new ProtocolCodecFilter(
//new TextLineCodecFactory()));
......
// Bind
acceptor.setHandler(/*our IoHandler*/);
acceptor.bind(new InetSocketAddress(port));

3. GitHub上面有哪些經典的java框架源碼

4. 求聊天系統中客戶端通信C/C++源代碼!!!

我有, 不是是基於Windows事件模型的 非同步的,封裝好的。頭文件和CPP都有。

5. android_studio手機藍牙串口通信源代碼

初涉android的藍牙操作,按照固定MAC地址連接獲取Device時,程序始終是異常終止,查了好多天代碼都沒查出原因。今天改了一下API版本,突然就成功連接了。總結之後發現果然是個坑爹之極的錯誤。

為了這種錯誤拚命查原因浪費大把時間是非常不值得的,但是問題不解決更是揪心。可惜我網路了那麼多,都沒有給出確切原因。今天特此mark,希望後來者遇到這個問題的時候能輕松解決。

下面是我的連接過程,中間崩潰原因及解決辦法。

1:用AT指令獲得藍牙串口的MAC地址,地址是簡寫的,按照常理猜測可得標准格式。

2:開一個String adress= "************" //MAC地址, String MY_UUID= "************"//UUID根據通信而定,網上都有。

3:取得本地Adapter用getDefaultAdapter(); 遠程的則用getRemoteDevice(adress); 之後便可用UUID開socket進行通信。

如果中途各種在getRemoteDevice處崩潰,大家可以查看一下當前的API版本,如果是2.1或以下版本的話,便能確定是API版本問題,只要換成2.2或者以上就都可以正常運行了~ 這么坑爹的錯誤的確很為難初學者。 唉·········· 為這種小trick浪費很多時間真是難過。

(另外有個重要地方,別忘了給manifest裡面加以下兩個藍牙操作許可權哦~)

6. 求一C語言寫的tcp程序的源碼,程序越簡單越好,C++也可以,最好帶注釋

最簡單的那種?我給你寫一個=,=
//伺服器
#include <sys/stat.h>

#include <fcntl.h>

#include <errno.h>

#include <netdb.h>

#include <sys/types.h>

#include <sys/socket.h>

#include <netinet/in.h>

#include <arpa/inet.h>

#include <string.h>

#include <stdlib.h>

#include <stdio.h>

#include <unistd.h>

main()

{
//創建套接字

int serverSocket= socket(AF_INET,SOCK_STREAM,0);

struct sockaddr_in server_addr;

struct sockaddr_in clientAddr;

int addr_len = sizeof(clientAddr);
int client;
char buffer[200];

//創建地址

bzero(&server_addr,sizeof(server_addr));

server_addr.sin_family =AF_INET;

server_addr.sin_port = htons(5555);

server_addr.sin_addr.s_addr = htonl(INADDR_ANY);

//綁定

bind(serverSocket,(struct sockaddr *)&server_addr,sizeof(server_addr));
//幀聽

listen(serverSocket,5);
printf("客戶端發過來的 :\n");
//接收
client=accept(serverSocket,(sockaddr *)&clientAddr,(socklen_t*)&addr_len);
printf("客戶端發過來的 :\n");
while(1)
{
if(recv(client,buffer,sizeof(buffer),0)>0)
printf("客戶端發過來的 : %s\n",buffer);
}
return 0;
}

//客戶端
#include <sys/stat.h>

#include <fcntl.h>

#include <errno.h>

#include <netdb.h>

#include <sys/types.h>

#include <sys/socket.h>

#include <netinet/in.h>

#include <arpa/inet.h>

#include <string.h>

#include <stdlib.h>

#include <stdio.h>

#include <unistd.h>

main()

{

struct sockaddr_in serverAddr;

int clientSocket=socket(AF_INET,SOCK_STREAM,0);

char sendbuf[200];

//創建地址信息

serverAddr.sin_family=AF_INET;

serverAddr.sin_port=htons(5555);

serverAddr.sin_addr.s_addr=inet_addr("127.0.0.1");

//連接伺服器

connect(clientSocket,(sockaddr*)&serverAddr,sizeof(serverAddr));

printf("連接目標主機中.....\n連接完成......\n");

//

while(1)

{

printf("請輸入發給伺服器的數據 : ");

scanf("%s",sendbuf);

//strcmp函數作用,比較兩個東東(按ASCII值大小相比較),相同就==0。

if(strcmp(sendbuf,"x")==0)

break;

send(clientSocket,sendbuf,sizeof(sendbuf),0);

}

close(clientSocket);

return 0;

}

7. 分析X-Scan,寫出它的使用方法以及配置方法,同時抓包分析其掃描原理。如果有興趣分析一下其腳本

.命令行:Xscan -h [起始地址]-[終止地址] [掃描選項]
這里如果只對一個ip進行掃描 就不需要填 終止地址了
掃描選項 這里 可以一次填多個 選項
[掃描選項]含義如下:
-p: 掃描標准埠(埠列表可通過\dat\config.ini文件定製);
-b: 獲取開放埠的banner信息,需要與-p參數合用;
-c: 掃描CGI漏洞;
-r: 掃描RPC漏洞;
-s: 掃描SQL-SERVER默認帳戶;
-f: 嘗試FTP默認用戶登錄(用戶名及口令可以通過\dat\config.ini文件定製);
-n: 獲取NetBios信息(若遠程主機操作系統為Windows9x/NT4.0/2000);
-g: 嘗試弱口令用戶連接(若遠程主機操作系統為Windows NT4.0/2000);
-a: 掃描以上全部內容;
-x [代理伺服器:埠]: 通過代理伺服器掃描CGI漏洞;
-t: 設置線程數量,默認為20個線程;
-v: 顯示詳細掃描進度;
-d: 禁止掃描前PING被掃主機。
2.示例:
Xscan -h 222.222.1.1-222.222.10.255 -a
含義:掃描XXX.XXX.1.1-XXX.XXX.10.255網段內主機的所有信息;
Xscan -h xxx.xxx.1.1 -n -g -t 30
含義:獲取XXX.XXX.1.1主機的Netbios信息,並檢測NT弱口令用戶,線程數量為30;
Xscan -h 211.108.1.1 -p -b -c -x 211.108.2.255:80 -v -d

我們來試一下
上面的這些參數都是需要大家來學習掌握的

現在我們進行一個簡單的cgi漏洞掃描,這次演練是在控制台模式下進行的:xscan 211.100.8.87 -port
這個命令是讓xscan掃描伺服器211.100.8.87的開放埠,掃描器不會對65535個埠全部進行掃描(太慢),它只會檢測網路上最常用的幾百個埠,而且每一個埠對應的網路服務在掃描器中都已經做過定義,從最後返回的結果很容易了解伺服器運行了什麼網路服務。掃描結果顯示如下:
Initialize dynamic library succeed.
Scanning 211.100.8.87 ......
[211.100.8.87]: Scaning port state ...
[211.100.8.87]: Port 21 is listening!!!
[211.100.8.87]: Port 25 is listening!!!
[211.100.8.87]: Port 53 is listening!!!
[211.100.8.87]: Port 79 is listening!!!
[211.100.8.87]: Port 80 is listening!!!
[211.100.8.87]: Port 110 is listening!!!
[211.100.8.87]: Port 3389 is listening!!!
[211.100.8.87]: Port scan completed, found 7.
[211.100.8.87]: All done.
這個結果還會同時在log目錄下生成一個html文檔,閱讀文檔可以了解發放的埠對應的服務項目

8. 在遠程shell工具里,用"wc"命令,計算一下linux源碼包里,總共包含了多少行源碼僅限

Linux系統越來越受到電腦用戶的歡迎,於是很多人開始學習Linux時,學習linux,你可能會遇到Linux網路操作命令問題,這里將介紹Linux網路操作命令知識,在這里拿出來和大家分享一下。計算機網路的主要優點是能夠實現資源和信息的共享,並且用戶可以遠程訪問信息。Linux提供了一組強有力的網路命令來為用戶服務,這些工具能夠幫助用戶登錄到遠程計算機上、傳輸文件和執行遠程命令等。介紹下列幾個常用的有關網路操作命令:ftp傳輸文件telnet登錄到遠程計算機上r-使用各種遠程命令netstat查看網路的狀況nslookup查詢域名和IP地址的對應finger查詢某個使用者的信息ping查詢某個機器是否在工作使用ftp命令進行遠程文件傳輸ftp命令是標準的文件傳輸協議的用戶介面。ftp是在TCP/IP網路上的計算機之間傳輸文件的簡單有效的方法。它允許用戶傳輸ASCII文件和二進制文件。在ftp會話過程中,用戶可以通過使用ftp客戶程序連接到另一台計算機上。從此,用戶可以在目錄中上下移動、列出目錄內容、把文件從遠程機拷貝到本地機上、把文件從本地機傳輸到遠程系統中。需要注意的是,如果用戶沒有那個文件的存取許可權,就不能從遠程系統中獲得文件或向遠程系統傳輸文件。為了使用ftp來傳輸文件,用戶必須知道遠程計算機上的合法用戶名和口令。這個用戶名/口令的組合用來確認ftp會話,並用來確定用戶對要傳輸的文件可以進行什麼樣的訪問。另外,用戶顯然需要知道對其進行ftp會話的計算機的名字或IP地址。Ftp命令的功能是在本地機和遠程機之間傳送文件。該命令的一般格式如下:$ftp主機名/IP其中「主機名/IP」是所要連接的遠程機的主機名或IP地址。在命令行中,主機名屬於選項,如果指定主機名,ftp將試圖與遠程機的ftp服務程序進行連接;如果沒有指定主機名,ftp將給出提示符,等待用戶輸入命令:$ftpftp>此時在ftp>提示符後面輸入open命令加主機名或IP地址,將試圖連接指定的主機。不管使用哪一種方法,如果連接成功,需要在遠程機上登錄。用戶如果在遠程機上有帳號,就可以通過ftp使用這一帳號並需要提供口令。在遠程機上的用戶帳號的讀寫許可權決定該用戶在遠程機上能下載什麼文件和將上載文件放到哪個目錄中。如果沒有遠程機的專用登錄帳號,許多ftp站點設有可以使用的特殊帳號。這個帳號的登錄名為anonymous(也稱為匿名ftp),當使用這一帳號時,要求輸入email地址作為口令。如果遠程系統提供匿名ftp服務,用戶使用這項服務可以登錄到特殊的,供公開使用的目錄。一般專門提供兩個目錄:pub目錄和incoming目錄。pub目錄包含該站點供公眾使用的所有文件,incoming目錄存放上載到該站點的文件。一旦用戶使用ftp在遠程站點上登錄成功,將得到「ftp>」提示符。現在可以自由使用ftp提供的命令,可以用help命令取得可供使用的命令清單,也可以在help命令後面指定具體的命令名稱,獲得這條命令的說明。最常用的命令有:ls列出遠程機的當前目錄cd在遠程機上改變工作目錄lcd在本地機上改變工作目錄ascii設置文件傳輸方式為ASCII模式binary設置文件傳輸方式為二進制模式close終止當前的ftp會話hash每次傳輸完數據緩沖區中的數據後就顯示一個#號get(mget)從遠程機傳送指定文件到本地機put(mput)從本地機傳送指定文件到遠程機open連接遠程ftp站點quit斷開與遠程機的連接並退出ftp?顯示本地幫助信息!轉到Shell中下面簡單將ftp常用命令作一簡介。啟動ftp會話open命令用於打開一個與遠程主機的會話。該命令的一般格式是:open主機名/IP如果在ftp會話期間要與一個以上的站點連接,通常只用不帶參數的ftp命令。如果在會話期間只想與一台計算機連接,那麼在命令行上指定遠程主機名或IP地址作為ftp命令的參數。終止ftp會話close、disconnect、quit和bye命令用於終止與遠程機的會話。close和disronnect命令關閉與遠程機的連接,但是使用戶留在本地計算機的ftp程序中。quit和bye命令都關閉用戶與遠程機的連接,然後退出用戶機上的ftp程序。改變目錄「cd[目錄]」命令用於在ftp會話期間改變遠程機上的目錄,lcd命令改變本地目錄,使用戶能指定查找或放置本地文件的位置。遠程目錄列表ls命令列出遠程目錄的內容,就像使用一個交互shell中的ls命令一樣。ls命令的一般格式是:ls[目錄][本地文件]如果指定了目錄作為參數,那麼ls就列出該目錄的內容。如果給出一個本地文件的名字,那麼這個目錄列表被放入本地機上您指定的這個文件中。從遠程系統獲取文件get和mget命令用於從遠程機上獲取文件。get命令的一般格式為:get文件名您還可以給出本地文件名,這個文件名是這個要獲取的文件在您的本地機上創建時的文件名。如果您不給出一個本地文件名,那麼就使用遠程文件原來的名字。mget命令一次獲取多個遠程文件。mget命令的一般格式為:mget文件名列表使用用空格分隔的或帶通配符的文件名列表來指定要獲取的文件,對其中的每個文件都要求用戶確認是否傳送。向遠程系統發送文件put和mput命令用於向遠程機發送文件。Put命令的一般格式為:put文件名mput命令一次發送多個本地文件,mput命令的一般格式為:mput文件名列表使用用空格分隔的或帶通配符的文件名列表來指定要發送的文件。對其中的每個文件都要求用戶確認是否發送。改變文件傳輸模式默認情況下,ftp按ASCII模式傳輸文件,用戶也可以指定其他模式。ascii和brinary命令的功能是設置傳輸的模式。用ASCII模式傳輸文件對純文本是非常好的,但為避免對二進制文件的破壞,用戶可以以二進制模式傳輸文件。檢查傳輸狀態傳輸大型文件時,可能會發現讓ftp提供關於傳輸情況的反饋信息是非常有用的。hash命令使ftp在每次傳輸完數據緩沖區中的數據後,就在屏幕上列印一個#字元。本命令在發送和接收文件時都可以使用。ftp中的本地命令當您使用ftp時,字元「!」用於向本地機上的命令shell傳送一個命令。如果用戶處在ftp會話中,需要shell做某些事,就很有用。例如用戶要建立一個目錄來保存接收到的文件。如果輸入!mkdirnew_dir,那麼Linux就在用戶當前的本地目錄中創建一個名為new_dir的目錄。從遠程機grunthos下載二進制數據文件的典型對話過程如下:$(grunthos:pc):anonymous33lGuestloginok,sendyourcompletee-mailaddressaspassword.Password:230Guest1oginok,accessrestrictionsapply.RemotesystemtypeisUNIX.ftp>cdpub250CWDcommandsuccessful.ftp>ls200PORTcommandsuccessful./bin/1s..ftp>binary200typesettoI.ftp>hashHashmarkprintingon(1024bytes/hashmark).ftp>.(l4684bytes).#############226Transfercomplete.14684bytesreceivedin0.0473secs(3e+02Kbytes/sec)ftp>quit22lGoodbye.使用telnet命令訪問遠程計算機用戶使用telnet命令進行遠程登錄。該命令允許用戶使用telnet協議在遠程計算機之間進行通信,用戶可以通過網路在遠程計算機上登錄,就像登錄到本地機上執行命令一樣。為了通過telnet登錄到遠程計算機上,必須知道遠程機上的合法用戶名和口令。雖然有些系統確實為遠程用戶提供登錄功能,但出於對安全的考慮,要限制來賓的操作許可權,因此,這種情況下能使用的功能是很少的。當允許遠程用戶登錄時,系統通常把這些用戶放在一個受限制的shell中,以防系統被懷有惡意的或不小心的用戶破壞。用戶還可以使用telnet從遠程站點登錄到自己的計算機上,檢查電子郵件、編輯文件和運行程序,就像在本地登錄一樣。但是,用戶只能使用基於終端的環境而不是XWndows環境,telnet只為普通終端提供終端模擬,而不支持XWndow等圖形環境。telnet命令的一般形式為:telnet主機名/IP其中「主機名/IP」是要連接的遠程機的主機名或IP地址。如果這一命令執行成功,將從遠程機上得到login:提示符。使用telnet命令登錄的過程如下:$telnet主機名/IP啟動telnet會話。一旦telnet成功地連接到遠程系統上,就顯示登錄信息並提示用戶輸人用戶名和口令。如果用戶名和口令輸入正確,就能成功登錄並在遠程系統上工作。在telnet提示符後面可以輸入很多命令,用來控制telnet會話過程,在telnet聯機幫助手冊中對這些命令有詳細的說明。下面是一台Linux計算機上的telnet會話舉例:$telnetserver.somewhere.comTrying127.0.0.1…Connectedtoserve.somewhere.com.Escapecharacteris\'?]\'.「TurboLinuxrelease4.0(Colgate)kernel2.0.18onanI486login:bubbapassword:Lastlogin:MonNovl520:50:43forlocalhostLinux2.0.6.(Posix).server:~$server:~$$用戶結束了遠程會話後,一定要確保使用logout命令退出遠程系統。然後telnet報告遠程會話被關閉,並返回到用戶的本地機的Shell提示符下。r-系列命令除ftp和telnet以外,還可以使用r-系列命令訪問遠程計算機和在網路上交換文件。使用r-系列命令需要特別注意,因為如果用戶不小心,就會造成嚴重的安全漏洞。用戶發出一個r-系列命令後,遠程系統檢查名為/etc/hosts.equiv的文件,以查看用戶的主機是否列在這個文件中。如果它沒有找到用戶的主機,就檢查遠程機上同名用戶的主目錄中名為.rhosts的文件,看是否包括該用戶的主機。如果該用戶的主機包括在這兩個文件中的任何一個之中,該用戶執行r-系列命令就不用提供口令。雖然用戶每次訪問遠程機時不用鍵入口令可能是非常方便的,但是它也可能會帶來嚴重的安全問題。我們建議用戶在建立/etc/hosts.equiv和.rhosts文件之前,仔細考慮r-命令隱含的安全問題。rlogin命令rlogin是「remotelogin」(遠程登錄)的縮寫。該命令與telnet命令很相似,允許用戶啟動遠程系統上的交互命令會話。rlogin的一般格式是:rlogin[-8EKLdx][-echar][-krealm][-lusername]host一般最常用的格式是:rloginhost該命令中各選項的含義為:-8此選項始終允許8位輸入數據通道。該選項允許發送格式化的ANSI字元和其他的特殊代碼。如果不用這個選項,除非遠端的終止和啟動字元不是或,否則就去掉奇偶校驗位。-E停止把任何字元當作轉義字元。當和-8選項一起使用時,它提供一個完全的透明連接。-K關閉所有的Kerberos確認。只有與使用Kerberos確認協議的主機連接時才使用這個選項。-L允許rlogin會話在litout模式中運行。要了解信息,請查閱tty聯機幫助。-d打開與遠程主機進行通信的TCPsockets的socket調試。要了解信息,請查閱setsockopt的聯機幫助。-e為rlogin會話設置轉義字元,默認的轉義字元是「~」,用戶可以指定一個文字字元或一個\\nnn形式的八進制數。-k請求rlogin獲得在指定區域內的遠程主機的Kerberos許可,而不是獲得由krb_realmofhost(3)確定的遠程主機區域內的遠程主機的Kerberos許可。-x為所有通過rlogin會話傳送的數據打開DES加密。這會影響響應時間和CPU利用率,但是可以提高安全性。rsh命令rsh是「remoteshell」(遠程shell)的縮寫。該命令在指定的遠程主機上啟動一個shell並執行用戶在rsh命令行中指定的命令。如果用戶沒有給出要執行的命令,rsh就用rlogin命令使用戶登錄到遠程機上。rsh命令的一般格式是:rsh[-Kdnx][-krealm][-lusername]host[command]一般常用的格式是:rshhost[command]command可以是從shell提示符下鍵人的任何Linux命令。rsh命令中各選項的含義如下:-K關閉所有的Kerbero確認。該選項只在與使用Kerbero確認的主機連接時才使用。-d打開與遠程主機進行通信的TCPsockets的socket調試。要了解的信息,請查閱setsockopt的聯機幫助。-k請求rsh獲得在指定區域內的遠程主機的Kerberos許可,而不是獲得由krb_relmofhost(3)確定的遠程主機區域內的遠程主機的Kerberos許可。-l預設情況下,遠程用戶名與本地用戶名相同。本選項允許指定遠程用戶名,如果指定了遠程用戶名,則使用Kerberos確認,與在rlogin命令中一樣。-n重定向來自特殊設備/dev/null的輸入。-x為傳送的所有數據打開DES加密。這會影響響應時間和CPU利用率,但是可以提高安全性。Linux把標准輸入放入rsh命令中,並把它拷貝到要遠程執行的命令的標准輸入中。它把遠程命令的標准輸出拷貝到rsh的標准輸出中。它還把遠程標准錯誤拷貝到本地標准錯誤文件中。任何退出、中止和中斷信號都被送到遠程命令中。當遠程命令終止了,rsh也就終止了。rcp命令rcp代表「remotefile」(遠程文件拷貝)。該命令用於在計算機之間拷貝文件。rcp命令有兩種格式。第一種格式用於文件到文件的拷貝;第二種格式用於把文件或目錄拷貝到另一個目錄中。rcp命令的一般格式是:rcp[-px][-krealm]file1file2rcp[-px][-r][-krealm]filedirectory每個文件或目錄參數既可以是遠程文件名也可以是本地文件名。遠程文件名具有如下形式:rname@rhost:path,其中rname是遠程用戶名,rhost是遠程計算機名,path是這個文件的路徑。rcp命令的各選項含義如下:-r遞歸地把源目錄中的所有內容拷貝到目的目錄中。要使用這個選項,目的必須是一個目錄。-p試圖保留源文件的修改時間和模式,忽略umask。-k請求rcp獲得在指定區域內的遠程主機的Kerberos許可,而不是獲得由krb_relmofhost(3)確定的遠程主機區域內的遠程主機的Kerberos許可。-x為傳送的所有數據打開DES加密。這會影響響應時間和CPU利用率,但是可以提高安全性。如果在文件名中指定的路徑不是完整的路徑名,那麼這個路徑被解釋為相對遠程機上同名用戶的主目錄。如果沒有給出遠程用戶名,就使用當前用戶名。如果遠程機上的路徑包含特殊shell字元,需要用反斜線(\\)、雙引號(」)或單引號(』)括起來,使所有的shell元字元都能被遠程地解釋。需要說明的是,rcp不提示輸入口令,它通過rsh命令來執行拷貝。-Turbolinux提供稿件。通過本文你就了解Linux網路操作命令,希望對你有所幫助。嘆號!進入ftpftp>help!!Escapetotheshell實際嘆號!新建shell要再ftp敲exit命令退新建shell即

9. socket 和mina 有區別嗎

MINA,Grizzly[grizzly-nio-framework],xSocket都是基於 java nio的 server framework.

這里的性能缺陷的焦點是指當一條channel上的SelectionKey.OP_READ ready時,1.是由select thread讀完數據之後再分發給應用程序的handler,2.還是直接就分發,由handler thread來負責讀數據和handle.

mina,xsocket是1. grizzly-nio-framework是2.

盡管讀channel buffer中bytes是很快的,但是如果我們放大,當連接channel達到上萬數量級,甚至更多,這種延遲響應的效果將會愈加明顯.

MINA:

for all selectedKeys

{

read data then fireMessageReceived.

}

xSocket:

for all selectedKeys

{

read data ,append it to readQueue then performOnData.

}

其中mina在fireMessageReceived時沒有使用threadpool來分發,所以需要應用程序在handler.messageReceived中再分發.而xsocket的performOnData默認是分發給threadpool[WorkerPool],WorkerPool雖然解決了線程池中的線程不能充到最大的問題[跟tomcat6的做法一樣],但是它的調度機制依然缺乏靈活性.

Grizzly:

for all selectedKeys

{

[NIOContext---filterChain.execute--->our filter.execute]<------run In DefaultThreadPool

}

grizzly的DefaultThreadPool幾乎重寫了java util concurrent threadpool,並使用自己的LinkedTransferQueue,但同樣缺乏靈活的池中線程的調度機制.下面分別是MINA,xSocket,Grizzly的源碼分析:

Apache MINA (mina-2.0.0-M6源碼為例):

我們使用mina nio tcp最常用的樣例如下:

NioSocketAcceptor acceptor = new NioSocketAcceptor(/*NioProcessorPool's size*/);
DefaultIoFilterChainBuilder chain = acceptor.getFilterChain();


//chain.addLast("codec", new ProtocolCodecFilter(
//new TextLineCodecFactory()));
......
// Bind
acceptor.setHandler(/*our IoHandler*/);
acceptor.bind(new InetSocketAddress(port));

------------------------------------------------------------------------------------

首先從NioSocketAcceptor(extends AbstractPollingIoAcceptor)開始,

bind(SocketAddress)--->bindInternal--->startupAcceptor:啟動AbstractPollingIoAcceptor.Acceptor.run使用executor[Executor]的線程,注冊[interestOps:SelectionKey.OP_ACCEPT],然後wakeup selector.

一旦有連接進來就構建NioSocketSession--對應--channal,然後session.getProcessor().add(session)將當前的channal加入到NioProcessor的selector中去[interestOps:SelectionKey.OP_READ],這樣每個連接中有請求過來就由相應的NioProcessor來處理.

這里有幾點要說明的是:
1.一個NioSocketAcceptor對應了多個NioProcessor,比如NioSocketAcceptor就使用了SimpleIoProcessorPool DEFAULT_SIZE = Runtime.getRuntime().availableProcessors() + 1.當然這個size在new NioSocketAcceptor的時候可以設定.
2.一個NioSocketAcceptor對應一個java nio selector[OP_ACCEPT],一個NioProcessor也對應一個java nio selector[OP_READ].
3.一個NioSocketAcceptor對應一個內部的AbstractPollingIoAcceptor.Acceptor---thread.
4.一個NioProcessor也對應一個內部的AbstractPollingIoProcessor.Processor---thread.
5.在new NioSocketAcceptor的時候如果你不提供Executor(線程池)的話,那麼默認使用Executors.newCachedThreadPool().
這個Executor將被NioSocketAcceptor和NioProcessor公用,也就是說上面的Acceptor---thread(一條)和Processor---thread(多條)都是源於這個Executor.

當一個連接java nio channal--NioSession被加到ProcessorPool[i]--NioProcessor中去後就轉入了AbstractPollingIoProcessor.Processor.run,
AbstractPollingIoProcessor.Processor.run方法是運行在上面的Executor中的一條線程中的,當前的NioProcessor將處理注冊在它的selector上的所有連接的請求[interestOps:SelectionKey.OP_READ].

AbstractPollingIoProcessor.Processor.run的主要執行流程:

for (;;) {
......
int selected = selector(final SELECT_TIMEOUT = 1000L);
.......
if (selected > 0) {
process();
}
......
}

process()-->for all session-channal:OP_READ -->read(session):這個read方法是AbstractPollingIoProcessor.private void read(T session)方法.
read(session)的主要執行流程是read channal-data to buf,if readBytes>0 then IoFilterChain.fireMessageReceived(buf)/*我們的IoHandler.messageReceived將在其中被調用*/;

到此mina Nio 處理請求的流程已經明了.

mina處理請求的線程模型也出來了,性能問題也來了,那就是在AbstractPollingIoProcessor.Processor.run-->process-->read(per session)中,在process的時候mina是for all selected-channals 逐次read data再fireMessageReceived到我們的IoHandler.messageReceived中,而不是並發處理,這樣一來很明顯後來的請求將被延遲處理.

我們假設:如果NioProcessorPool's size=2 現在有200個客戶端同時連接過來,假設每個NioProcessor都注冊了100個連接,對於每個NioProcessor將依次順序處理這100個請求,那麼這其中的第100個請求要得到處理,那它只有等到前面的99個被處理完了.
有人提出了改進方案,那就是在我們自己的IoHandler.messageReceived中利用線程池再進行分發dispatching,這個當然是個好主意.
但是請求還是被延遲處理了,因為還有read data所消耗的時間,這樣第100個請求它的數據要被讀,就要等前面的99個都被讀完才行,即便是增加ProcessorPool的尺寸也不能解決這個問題.

此外mina的陷阱(這個詞較時髦)也出來了,就是在read(session)中,在說這個陷阱之前先說明一下,我們的client端向server端發送一個消息體的時候不一定是完整的只發送一次,可能分多次發送,特別是在client端忙或要發送的消息體的長度較長的時候.而mina在這種情況下就會call我們的IoHandler.messageReceived多次,結果就是消息體被分割了若干份,等於我們在IoHandler.messageReceived中每次處理的數據都是不完整的,這會導致數據丟失,無效.
下面是read(session)的源碼:
private void read(T session) {
IoSessionConfig config = session.getConfig();
IoBuffer buf = IoBuffer.allocate(config.getReadBufferSize());

final boolean hasFragmentation =
session.getTransportMetadata().hasFragmentation();

try {
int readBytes = 0;
int ret;

try {
if (hasFragmentation/*hasFragmentation一定為ture,也許mina的開發人員也意識到了傳輸數據的碎片問題,但是靠下面的處理是遠遠不夠的,因為client一旦間隔發送,ret就可能為0,退出while,不完整的readBytes將被fire*/) {
while ((ret = read(session, buf)) > 0) {
readBytes += ret;
if (!buf.hasRemaining()) {
break;
}
}
} else {
ret = read(session, buf);
if (ret > 0) {
readBytes = ret;
}
}
} finally {
buf.flip();
}

if (readBytes > 0) {
IoFilterChain filterChain = session.getFilterChain();
filterChain.fireMessageReceived(buf);
buf = null;

if (hasFragmentation) {
if (readBytes << 1 < config.getReadBufferSize()) {
session.decreaseReadBufferSize();
} else if (readBytes == config.getReadBufferSize()) {
session.increaseReadBufferSize();
}
}
}
if (ret < 0) {
scheleRemove(session);
}
} catch (Throwable e) {
if (e instanceof IOException) {
scheleRemove(session);
}
IoFilterChain filterChain = session.getFilterChain();
filterChain.fireExceptionCaught(e);
}
}
這個陷阱大家可以測試一下,看會不會一個完整的消息被多次發送,你的IoHandler.messageReceived有沒有被多次調用.
要保持我們應用程序消息體的完整性也很簡單只需創建一個斷點breakpoint,然後set it to the current IoSession,一旦消息體數據完整就dispatching it and remove it from the current session.

--------------------------------------------------------------------------------------------------

下面以xSocket v2_8_8源碼為例:

tcp usage e.g:

IServer srv = new Server(8090, new EchoHandler());
srv.start() or run();

-----------------------------------------------------------------------

class EchoHandler implements IDataHandler {
public boolean onData(INonBlockingConnection nbc)
throws IOException,
BufferUnderflowException,
MaxReadSizeExceededException {
String data = nbc.readStringByDelimiter("/r/n");
nbc.write(data + "/r/n");
return true;
}
}

------------------------------------------------------------------------

說明1.Server:Acceptor:IDataHandler ------1:1:1

Server.run-->IoAcceptor.accept()在port上阻塞,一旦有channel就從IoSocketDispatcherPool中獲取一個IoSocketDispatcher,同時構建一個IoSocketHandler和NonBlockingConnection,調用

Server.LifeCycleHandler.onConnectionAccepted(ioHandler) initialize the IoSocketHandler.注意:IoSocketDispatcherPool.size默認為2,也就是說只有2條do select的線程和相應的2個IoSocketDispatcher.這個和MINA的NioProcessor數是一樣的.

說明2.IoSocketDispatcher[java nio Selector]:IoSocketHandler:NonBlockingConnection------1:1:1

在IoSocketDispatcher[對應一個Selector].run中--->IoSocketDispatcher.handleReadWriteKeys:

for all selectedKeys

{

IoSocketHandler.onReadableEvent/onWriteableEvent.

}

IoSocketHandler.onReadableEvent的處理過程如下:

1.readSocket();

2.NonBlockingConnection.IoHandlerCallback.onData

NonBlockingConnection.onData--->appendDataToReadBuffer: readQueue append data

3.NonBlockingConnection.IoHandlerCallback.onPostData

NonBlockingConnection.onPostData--->HandlerAdapter.onData[our dataHandler] performOnData in WorkerPool[threadpool].因為是把channel中的數據讀到readQueue中,應用程序的dataHandler.onData會被多次調用直到readQueue中的數據讀完為止.所以依然存在類似mina的陷阱.解決的方法依然類似,因為這里有NonBlockingConnection.

----------------------------------------------------------------------------------------------

再下面以grizzly-nio-framework v1.9.18源碼為例:

tcp usage e.g:

Controller sel = new Controller();
sel.(new (){
public ProtocolChain poll() {
ProtocolChain protocolChain = protocolChains.poll();
if (protocolChain == null){
protocolChain = new DefaultProtocolChain();
//protocolChain.addFilter(our app's filter/*應用程序的處理從filter開始,類似mina.ioHandler,xSocket.dataHandler*/);
//protocolChain.addFilter(new ReadFilter());
}
return protocolChain;
}
});

//如果你不增加自己的SelectorHandler,Controller就默認使用TCPSelectorHandler port:18888
sel.addSelectorHandler(our app's selectorHandler on special port);
sel.start();

------------------------------------------------------------------------------------------------------------

說明1.Controller:ProtocolChain:Filter------1:1:n,

Controller:SelectorHandler------1:n,SelectorHandler[對應一個Selector]:SelectorHandlerRunner------1:1,

Controller. start()--->for per SelectorHandler start SelectorHandlerRunner to run.

SelectorHandlerRunner.run()--->selectorHandler.select() then handleSelectedKeys:

for all selectedKeys

{

NIOContext.execute:dispatching to threadpool for ProtocolChain.execute--->our filter.execute.

}你會發現這里沒有read data from channel的動作,因為這將由你的filter來完成.所以自然沒有mina,xsocket它們的陷阱問題,分發提前了.但是你要注意SelectorHandler:Selector:SelectorHandlerRunner:Thread[SelectorHandlerRunner.run]都是1:1:1:1,也就是說只有一條線程在doSelect then handleSelectedKeys.
相比之下雖然grizzly在並發性能上更優,但是在易用性方面卻不如mina,xsocket,比如類似mina,xsocket中表示當前連接或會話的IoSession,INonBlockingConnection對象在grizzly中由NIOContext來負責,但是NIOContext並沒有提供session/connection lifecycle event,以及常規的read/write操作,這些都需要你自己去擴展SelectorHandler和ProtocolFilter,從另一個方面也可以說明grizzly的可擴展性,靈活性更勝一籌.
轉載

10. php100 socket類源碼

email.class.php <?php class smtp { /* Public Variables */ var $smtp_port; var $time_out; var $host_name; var $log_file; var $relay_host; var $debug; var $auth; var $user; var $pass; /* Private Variables */ var $sock; /* Constractor */ function smtp($relay_host = "", $smtp_port = 25,$auth = false,$user,$pass) { $this->debug = FALSE; $this->smtp_port = $smtp_port; $this->relay_host = $relay_host; $this->time_out = 30; //is used in fsockopen() # $this->auth = $auth;//auth $this->user = $user; $this->pass = $pass; # $this->host_name = "localhost"; //is used in HELO command $this->log_file =""; $this->sock = FALSE; } /* Main Function */ function sendmail($to, $from, $subject = "", $body = "", $mailtype, $cc = "", $bcc = "", $additional_headers = "") { $mail_from = $this->get_address($this->strip_comment($from)); $body = ereg_replace("(^|(\r\n))(\\.)", "\\1.\\3", $body); $header .= "MIME-Version:1.0\r\n"; if($mailtype=="HTML"){ $header .= "Content-Type:text/html\r\n"; } $header .= "To: ".$to."\r\n"; if ($cc != "") { $header .= "Cc: ".$cc."\r\n"; } $header .= "From: $from<".$from.">\r\n"; $header .= "Subject: ".$subject."\r\n"; $header .= $additional_headers; $header .= "Date: ".date("r")."\r\n"; $header .= "X-Mailer:By Redhat (PHP/".phpversion().")\r\n"; list($msec, $sec) = explode(" ", microtime()); $header .= "Message-ID: <".date("YmdHis", $sec).".".($msec*1000000).".".$mail_from.">\r\n"; $TO = explode(",", $this->strip_comment($to)); if ($cc != "") { $TO = array_merge($TO, explode(",", $this->strip_comment($cc))); } if ($bcc != "") { $TO = array_merge($TO, explode(",", $this->strip_comment($bcc))); } $sent = TRUE; foreach ($TO as $rcpt_to) { $rcpt_to = $this->get_address($rcpt_to); if (!$this->smtp_sockopen($rcpt_to)) { $this->log_write("Error: Cannot send email to ".$rcpt_to."\n"); $sent = FALSE; continue; } if ($this->smtp_send($this->host_name, $mail_from, $rcpt_to, $header, $body)) { $this->log_write("E-mail has been sent to <".$rcpt_to.">\n"); } else { $this->log_write("Error: Cannot send email to <".$rcpt_to.">\n"); $sent = FALSE; } fclose($this->sock); $this->log_write("Disconnected from remote host\n"); } echo "<br>"; echo $header; return $sent; } /* Private Functions */ function smtp_send($helo, $from, $to, $header, $body = "") { if (!$this->smtp_putcmd("HELO", $helo)) { return $this->smtp_error("sending HELO command"); } #auth if($this->auth){ if (!$this->smtp_putcmd("AUTH LOGIN", base64_encode($this->user))) { return $this->smtp_error("sending HELO command"); } if (!$this->smtp_putcmd("", base64_encode($this->pass))) { return $this->smtp_error("sending HELO command"); } } # if (!$this->smtp_putcmd("MAIL", "FROM:<".$from.">")) { return $this->smtp_error("sending MAIL FROM command"); } if (!$this->smtp_putcmd("RCPT", "TO:<".$to.">")) { return $this->smtp_error("sending RCPT TO command"); } if (!$this->smtp_putcmd("DATA")) { return $this->smtp_error("sending DATA command"); } if (!$this->smtp_message($header, $body)) { return $this->smtp_error("sending message"); } if (!$this->smtp_eom()) { return $this->smtp_error("sending <CR><LF>.<CR><LF> [EOM]"); } if (!$this->smtp_putcmd("QUIT")) { return $this->smtp_error("sending QUIT command"); } return TRUE; } function smtp_sockopen($address) { if ($this->relay_host == "") { return $this->smtp_sockopen_mx($address); } else { return $this->smtp_sockopen_relay(); } } function smtp_sockopen_relay() { $this->log_write("Trying to ".$this->relay_host.":".$this->smtp_port."\n"); $this->sock = @fsockopen($this->relay_host, $this->smtp_port, $errno, $errstr, $this->time_out); if (!($this->sock && $this->smtp_ok())) { $this->log_write("Error: Cannot connenct to relay host ".$this->relay_host."\n"); $this->log_write("Error: ".$errstr." (".$errno.")\n"); return FALSE; } $this->log_write("Connected to relay host ".$this->relay_host."\n"); return TRUE;; } function smtp_sockopen_mx($address) { $domain = ereg_replace("^.+@([^@]+)$", "\\1", $address); if (!@getmxrr($domain, $MXHOSTS)) { $this->log_write("Error: Cannot resolve MX \"".$domain."\"\n"); return FALSE; } foreach ($MXHOSTS as $host) { $this->log_write("Trying to ".$host.":".$this->smtp_port."\n"); $this->sock = @fsockopen($host, $this->smtp_port, $errno, $errstr, $this->time_out); if (!($this->sock && $this->smtp_ok())) { $this->log_write("Warning: Cannot connect to mx host ".$host."\n"); $this->log_write("Error: ".$errstr." (".$errno.")\n"); continue; } $this->log_write("Connected to mx host ".$host."\n"); return TRUE; } $this->log_write("Error: Cannot connect to any mx hosts (".implode(", ", $MXHOSTS).")\n"); return FALSE; } function smtp_message($header, $body) { fputs($this->sock, $header."\r\n".$body); $this->smtp_debug("> ".str_replace("\r\n", "\n"."> ", $header."\n> ".$body."\n> ")); return TRUE; } function smtp_eom() { fputs($this->sock, "\r\n.\r\n"); $this->smtp_debug(". [EOM]\n"); return $this->smtp_ok(); } function smtp_ok() { $response = str_replace("\r\n", "", fgets($this->sock, 512)); $this->smtp_debug($response."\n"); if (!ereg("^[23]", $response)) { fputs($this->sock, "QUIT\r\n"); fgets($this->sock, 512); $this->log_write("Error: Remote host returned \"".$response."\"\n"); return FALSE; } return TRUE; } function smtp_putcmd($cmd, $arg = "") { if ($arg != "") { if($cmd=="") $cmd = $arg; else $cmd = $cmd." ".$arg; } fputs($this->sock, $cmd."\r\n"); $this->smtp_debug("> ".$cmd."\n"); return $this->smtp_ok(); } function smtp_error($string) { $this->log_write("Error: Error occurred while ".$string.".\n"); return FALSE; } function log_write($message) { $this->smtp_debug($message); if ($this->log_file == "") { return TRUE; } $message = date("M d H:i:s ").get_current_user()."[".getmypid()."]: ".$message; if (!@file_exists($this->log_file) || !($fp = @fopen($this->log_file, "a"))) { $this->smtp_debug("Warning: Cannot open log file \"".$this->log_file."\"\n"); return FALSE; } flock($fp, LOCK_EX); fputs($fp, $message); fclose($fp); return TRUE; } function strip_comment($address) { $comment = "\\([^()]*\\)"; while (ereg($comment, $address)) { $address = ereg_replace($comment, "", $address); } return $address; } function get_address($address) { $address = ereg_replace("([ \t\r\n])+", "", $address); $address = ereg_replace("^.*<(.+)>.*$", "\\1", $address); return $address; } function smtp_debug($message) { if ($this->debug) { echo $message."<br>"; } } function get_attach_type($image_tag) { // $filedata = array(); $img_file_con=fopen($image_tag,"r"); unset($image_data); while ($tem_buffer=AddSlashes(fread($img_file_con,filesize($image_tag)))) $image_data.=$tem_buffer; fclose($img_file_con); $filedata['context'] = $image_data; $filedata['filename']= basename($image_tag); $extension=substr($image_tag,strrpos($image_tag,"."),strlen($image_tag)-strrpos($image_tag,".")); switch($extension){ case ".gif": $filedata['type'] = "image/gif"; break; case ".gz": $filedata['type'] = "application/x-gzip"; break; case ".htm": $filedata['type'] = "text/html"; break; case ".html": $filedata['type'] = "text/html"; break; case ".jpg": $filedata['type'] = "image/jpeg"; break; case ".tar": $filedata['type'] = "application/x-tar"; break; case ".txt": $filedata['type'] = "text/plain"; break; case ".zip": $filedata['type'] = "application/zip"; break; default: $filedata['type'] = "application/octet-stream"; break; } return $filedata; } } ?> ----------------------------------------- sendmail.php <?php require_once ('email.class.php'); //########################################## $smtpserver = "smtp.163.com";//SMTP伺服器 $smtpserverport =25;//SMTP伺服器埠 $smtpusermail = "";//SMTP伺服器的用戶郵箱 $smtpemailto = "";//發送給誰 $smtpuser = "";//SMTP伺服器的用戶帳號 $smtppass = "";//SMTP伺服器的用戶密碼 $mailsubject = "PHP100測試郵件系統";//郵件主題 $mailbody = "<h1> 這是一個測試程序 PHP100.com </h1>";//郵件內容 $mailtype = "HTML";//郵件格式(HTML/TXT),TXT為文本郵件 ########################################## $smtp = new smtp($smtpserver,$smtpserverport,true,$smtpuser,$smtppass);//這裡面的一個true是表示使用身份驗證,否則不使用身份驗證. $smtp->debug = FALSE;//是否顯示發送的調試信息 $smtp->sendmail($smtpemailto, $smtpusermail, $mailsubject, $mailbody, $mailtype); ?>

閱讀全文

與xsocket源碼相關的資料

熱點內容
輕閱讀的伺服器的地址是什麼 瀏覽:957
得力app如何刪除設備 瀏覽:603
怎麼把伺服器卡死 瀏覽:479
ug加密的key文件 瀏覽:165
編程理論基礎 瀏覽:311
安卓boot配置文件都有什麼 瀏覽:534
數量關系排序演算法 瀏覽:184
serv文件怎麼傳到伺服器上 瀏覽:274
開發者聯名貢獻源碼 瀏覽:338
sae部署java 瀏覽:18
校園330app怎麼下載 瀏覽:23
javahashcode演算法 瀏覽:714
pdf轉doc手機軟體 瀏覽:531
方舟手游開伺服器機床怎麼選 瀏覽:255
qt編程入門pdf下載 瀏覽:784
java編程的三個步驟 瀏覽:776
s點b點主圖源碼 瀏覽:436
電腦可以刪除的臨時文件夾 瀏覽:9
小杜app上怎麼啟用 瀏覽:305
為什麼伺服器喇叭喊了一次就不行 瀏覽:480