版權(quán)說(shuō)明:本文檔由用戶提供并上傳,收益歸屬內(nèi)容提供方,若內(nèi)容存在侵權(quán),請(qǐng)進(jìn)行舉報(bào)或認(rèn)領(lǐng)
文檔簡(jiǎn)介
PHP的Socket網(wǎng)絡(luò)編程入門指引一般人認(rèn)為php的用途就是簡(jiǎn)單的網(wǎng)站建設(shè),其實(shí)php語(yǔ)言也可以進(jìn)行高深層次的網(wǎng)站功能性開發(fā),這篇文章通過案例演示詳細(xì)介紹了php的socket通信,對(duì)每一段代碼進(jìn)行了分析,每一步驟都配有詳細(xì)說(shuō)明,感興趣的的朋友可以參考下對(duì)TCP/IP、UDP、Socket編程這些詞你不會(huì)很陌生吧?隨著網(wǎng)絡(luò)技術(shù)的發(fā)展,這些詞充斥著我們的耳朵。那什么是TCP/IP、UDP?
TCP/IP(TransmissionControlProtocol/InternetProtocol)即傳輸控制協(xié)議/網(wǎng)間協(xié)議,是一個(gè)工業(yè)標(biāo)準(zhǔn)的協(xié)議集,它是為廣域網(wǎng)(WANs)設(shè)計(jì)的。
UDP(UserDataProtocol,用戶數(shù)據(jù)報(bào)協(xié)議)是與TCP相對(duì)應(yīng)的協(xié)議。它是屬于TCP/IP協(xié)議族中的一種。
這里有一張圖,表明了這些協(xié)議的關(guān)系。TCP/IP協(xié)議族包括運(yùn)輸層、網(wǎng)絡(luò)層、鏈路層。現(xiàn)在你知道TCP/IP與UDP的關(guān)系了吧。
Socket在哪里呢?
在圖1中,我們沒有看到Socket的影子,那么它到底在哪里呢?還是用圖來(lái)說(shuō)話,一目了然。原來(lái)Socket在這里。
Socket是什么呢?
Socket是應(yīng)用層與TCP/IP協(xié)議族通信的中間軟件抽象層,它是一組接口。在設(shè)計(jì)模式中,Socket其實(shí)就是一個(gè)門面模式,它把復(fù)雜的TCP/IP協(xié)議族隱藏在Socket接口后面,對(duì)用戶來(lái)說(shuō),一組簡(jiǎn)單的接口就是全部,讓Socket去組織數(shù)據(jù),以符合指定的協(xié)議。
你會(huì)使用它們嗎?
前人已經(jīng)給我們做了好多的事了,網(wǎng)絡(luò)間的通信也就簡(jiǎn)單了許多,但畢竟還是有挺多工作要做的。以前聽到Socket編程,覺得它是比較高深的編程知識(shí),但是只要弄清Socket編程的工作原理,神秘的面紗也就揭開了。
一個(gè)生活中的場(chǎng)景。你要打電話給一個(gè)朋友,先撥號(hào),朋友聽到電話鈴聲后提起電話,這時(shí)你和你的朋友就建立起了連接,就可以講話了。等交流結(jié)束,掛斷電話結(jié)束此次交談。生活中的場(chǎng)景就解釋了這工作原理,也許TCP/IP協(xié)議族就是誕生于生活中,這也不一定。先從服務(wù)器端說(shuō)起。服務(wù)器端先初始化Socket,然后與端口綁定(bind),對(duì)端口進(jìn)行監(jiān)聽(listen),調(diào)用accept阻塞,等待客戶端連接。在這時(shí)如果有個(gè)客戶端初始化一個(gè)Socket,然后連接服務(wù)器(connect),如果連接成功,這時(shí)客戶端與服務(wù)器端的連接就建立了??蛻舳税l(fā)送數(shù)據(jù)請(qǐng)求,服務(wù)器端接收請(qǐng)求并處理請(qǐng)求,然后把回應(yīng)數(shù)據(jù)發(fā)送給客戶端,客戶端讀取數(shù)據(jù),最后關(guān)閉連接,一次交互結(jié)束。socket相關(guān)函數(shù):
----------------------------------------------------------------------------------------------
socket_accept()接受一個(gè)Socket連接
socket_bind()把socket綁定在一個(gè)IP地址和端口上
socket_clear_error()清除socket的錯(cuò)誤或者最后的錯(cuò)誤代碼
socket_close()關(guān)閉一個(gè)socket資源
socket_connect()開始一個(gè)socket連接
socket_create_listen()在指定端口打開一個(gè)socket監(jiān)聽
socket_create_pair()產(chǎn)生一對(duì)沒有區(qū)別的socket到一個(gè)數(shù)組里
socket_create()產(chǎn)生一個(gè)socket,相當(dāng)于產(chǎn)生一個(gè)socket的數(shù)據(jù)結(jié)構(gòu)
socket_get_option()獲取socket選項(xiàng)
socket_getpeername()獲取遠(yuǎn)程類似主機(jī)的ip地址
socket_getsockname()獲取本地socket的ip地址
socket_iovec_add()添加一個(gè)新的向量到一個(gè)分散/聚合的數(shù)組
socket_iovec_alloc()這個(gè)函數(shù)創(chuàng)建一個(gè)能夠發(fā)送接收讀寫的iovec數(shù)據(jù)結(jié)構(gòu)
socket_iovec_delete()刪除一個(gè)已經(jīng)分配的iovec
socket_iovec_fetch()返回指定的iovec資源的數(shù)據(jù)
socket_iovec_free()釋放一個(gè)iovec資源
socket_iovec_set()設(shè)置iovec的數(shù)據(jù)新值
socket_last_error()獲取當(dāng)前socket的最后錯(cuò)誤代碼
socket_listen()監(jiān)聽由指定socket的所有連接
socket_read()讀取指定長(zhǎng)度的數(shù)據(jù)
socket_readv()讀取從分散/聚合數(shù)組過來(lái)的數(shù)據(jù)
socket_recv()從socket里結(jié)束數(shù)據(jù)到緩存
socket_recvfrom()接受數(shù)據(jù)從指定的socket,如果沒有指定則默認(rèn)當(dāng)前socket
socket_recvmsg()從iovec里接受消息
socket_select()多路選擇
socket_send()這個(gè)函數(shù)發(fā)送數(shù)據(jù)到已連接的socket
socket_sendmsg()發(fā)送消息到socket
socket_sendto()發(fā)送消息到指定地址的socket
socket_set_block()在socket里設(shè)置為塊模式
socket_set_nonblock()socket里設(shè)置為非塊模式
socket_set_option()設(shè)置socket選項(xiàng)
socket_shutdown()這個(gè)函數(shù)允許你關(guān)閉讀、寫、或者指定的socket
socket_strerror()返回指定錯(cuò)誤號(hào)的詳細(xì)錯(cuò)誤
socket_write()寫數(shù)據(jù)到socket緩存
socket_writev()寫數(shù)據(jù)到分散/聚合數(shù)組案例一:socket通信演示服務(wù)器端:?11<?php2//確保在連接客戶端時(shí)不會(huì)超時(shí)3set_time_limit(0);45$ip='';6$port=1935;78/*9+-------------------------------10*@socket通信整個(gè)過程11+-------------------------------12*@socket_create13*@socket_bind14*@socket_listen15*@socket_accept16*@socket_read17*@socket_write18*@socket_close19+--------------------------------20*/2122/*----------------以下操作都是手冊(cè)上的-------------------*/23if(($sock=socket_create(AF_INET,SOCK_STREAM,SOL_TCP))<0){24echo"socket_create()失敗的原因是:".socket_strerror($sock)."\n";25}2627if(($ret=socket_bind($sock,$ip,$port))<0){28echo"socket_bind()失敗的原因是:".socket_strerror($ret)."\n";29}3031if(($ret=socket_listen($sock,4))<0){32echo"socket_listen()失敗的原因是:".socket_strerror($ret)."\n";33}3435$count=0;3637do{38if(($msgsock=socket_accept($sock))<0){39echo"socket_accept()failed:reason:".socket_strerror($msgsock)."\n";40break;41}else{4243//發(fā)到客戶端44$msg="測(cè)試成功!\n";45socket_write($msgsock,$msg,strlen($msg));4647echo"測(cè)試成功了啊\n";48$buf=socket_read($msgsock,8192);495051$talkback="收到的信息:$buf\n";52echo$talkback;5354if(++$count>=5){55break;56};575859}60//echo$buf;61socket_close($msgsock);6263}while(true);6465socket_close($sock);66?>這是socket的服務(wù)端代碼。然后運(yùn)行cmd,注意是自己的程序存放路徑啊。沒有反映,對(duì)現(xiàn)在服務(wù)端的程序已經(jīng)開始運(yùn)行,端口已經(jīng)開始監(jiān)聽了。運(yùn)行netstat-ano可以查看端口情況,我的是1935端口看,端口已經(jīng)處于LISTENING狀態(tài)了。接下來(lái)我們只要運(yùn)行客戶端程序即可連接上。上代碼?11<?php2error_reporting(E_ALL);3set_time_limit(0);4echo"<h2>TCP/IPConnection</h2>\n";56$port=1935;7$ip="";89/*10+-------------------------------11*@socket連接整個(gè)過程12+-------------------------------13*@socket_create14*@socket_connect15*@socket_write16*@socket_read17*@socket_close18+--------------------------------19*/2021$socket=socket_create(AF_INET,SOCK_STREAM,SOL_TCP);22if($socket<0){23echo"socket_create()failed:reason:".socket_strerror($socket)."\n";24}else{25echo"OK.\n";26}2728echo"試圖連接'$ip'端口'$port'...\n";29$result=socket_connect($socket,$ip,$port);30if($result<0){31echo"socket_connect()failed.\nReason:($result)".socket_strerror($result)."\n";32}else{33echo"連接OK\n";34}3536$in="Ho\r\n";37$in.="firstblood\r\n";38$out='';3940if(!socket_write($socket,$in,strlen($in))){41echo"socket_write()failed:reason:".socket_strerror($socket)."\n";42}else{43echo"發(fā)送到服務(wù)器信息成功!\n";44echo"發(fā)送的內(nèi)容為:<fontcolor='red'>$in</font><br>";45}4647while($out=socket_read($socket,8192)){48echo"接收服務(wù)器回傳信息成功!\n";49echo"接受的內(nèi)容為:",$out;50}515253echo"關(guān)閉SOCKET...\n";54socket_close($socket);55echo"關(guān)閉OK\n";56?>至此客戶端已經(jīng)連接上服務(wù)端了。案例二:代碼詳解?12345678910111213141516171819202122232425//設(shè)置一些基本的變量$host="9";$port=1234;//設(shè)置超時(shí)時(shí)間set_time_limit(0);//創(chuàng)建一個(gè)Socket$socket=socket_create(AF_INET,SOCK_STREAM,0)ordie("Wnotcreatesocket\n");//綁定Socket到端口$result=socket_bind($socket,$host,$port)ordie("Wnotbindtosocket\n");//開始監(jiān)聽鏈接$result=socket_listen($socket,3)ordie("Wnotsetupsocketlistener\n");//acceptincomingconnections//另一個(gè)Socket來(lái)處理通信$spawn=socket_accept($socket)ordie("Wnotacceptincomingconnection\n");//獲得客戶端的輸入$input=socket_read($spawn,1024)ordie("Wnotreadinput\n");//清空輸入字符串$input=trim($input);//處理客戶端輸入并返回結(jié)果$output=strrev($input)."\n";socket_write($spawn,$output,strlen($output))ordie("Wnotwriteoutput\n");//關(guān)閉socketssocket_close($spawn);socket_close($socket);下面是其每一步驟的詳細(xì)說(shuō)明:1.第一步是建立兩個(gè)變量來(lái)保存Socket運(yùn)行的服務(wù)器的IP地址和端口.你可以設(shè)置為你自己的服務(wù)器和端口(這個(gè)端口可以是1到65535之間的數(shù)字),前提是這個(gè)端口未被使用.[Copytoclipboard]
PHPCODE:?123//設(shè)置兩個(gè)變量$host="9";$port=1234;2.在服務(wù)器端可以使用set_time_out()函數(shù)來(lái)確保PHP在等待客戶端連接時(shí)不會(huì)超時(shí).[Copytoclipboard]
PHPCODE:?12//超時(shí)時(shí)間set_time_limit(0);3.在前面的基礎(chǔ)上,現(xiàn)在該使用socket_creat()函數(shù)創(chuàng)建一個(gè)Socket了—這個(gè)函數(shù)返回一個(gè)Socket句柄,這個(gè)句柄將用在以后所有的函數(shù)中.[Copytoclipboard]
PHPCODE:?123//創(chuàng)建Socket$socket=socket_create(AF_INET,SOCK_STREAM,0)ordie("Wnotcreatesocket\n");第一個(gè)參數(shù)”AF_INET”用來(lái)指定域名;
第二個(gè)參數(shù)”SOCK_STREM”告訴函數(shù)將創(chuàng)建一個(gè)什么類型的Socket(在這個(gè)例子中是TCP類型)因此,如果你想創(chuàng)建一個(gè)UDPSocket的話,你可以使用如下的代碼:[Copytoclipboard]
PHPCODE:?123//創(chuàng)建socket$socket=socket_create(AF_INET,SOCK_DGRAM,0)ordie("Wnotcreatesocket\n");4.一旦創(chuàng)建了一個(gè)Socket句柄,下一步就是指定或者綁定它到指定的地址和端口.這可以通過socket_bind()函數(shù)來(lái)完成.[Copytoclipboard]
PHPCODE:?123//綁定socketto指定地址和端口$result=socket_bind($socket,$host,$port)ordie("Wnotbindtosocket\n");5.當(dāng)Socket被創(chuàng)建好并綁定到一個(gè)端口后,就可以開始監(jiān)聽外部的連接了.PHP允許你由socket_listen()函數(shù)來(lái)開始一個(gè)監(jiān)聽,同時(shí)你可以指定一個(gè)數(shù)字(在這個(gè)例子中就是第二個(gè)參數(shù):3)[Copytoclipboard]
PHPCODE:?123//開始監(jiān)聽連接$result=socket_listen($socket,3)ordie("Wnotsetupsocketlistener\n");6.到現(xiàn)在,你的服務(wù)器除了等待來(lái)自客戶端的連接請(qǐng)求外基本上什么也沒有做.一旦一個(gè)客戶端的連接被收到,socket_accept()函數(shù)便開始起作用了,它接收連接請(qǐng)求并調(diào)用另一個(gè)子Socket來(lái)處理客戶端–服務(wù)器間的信息.[Copytoclipboard]
PHPCODE:?1234//接受請(qǐng)求鏈接//調(diào)用子socket處理信息$spawn=socket_accept($socket)ordie("Wnotacceptincomingconnectio
溫馨提示
- 1. 本站所有資源如無(wú)特殊說(shuō)明,都需要本地電腦安裝OFFICE2007和PDF閱讀器。圖紙軟件為CAD,CAXA,PROE,UG,SolidWorks等.壓縮文件請(qǐng)下載最新的WinRAR軟件解壓。
- 2. 本站的文檔不包含任何第三方提供的附件圖紙等,如果需要附件,請(qǐng)聯(lián)系上傳者。文件的所有權(quán)益歸上傳用戶所有。
- 3. 本站RAR壓縮包中若帶圖紙,網(wǎng)頁(yè)內(nèi)容里面會(huì)有圖紙預(yù)覽,若沒有圖紙預(yù)覽就沒有圖紙。
- 4. 未經(jīng)權(quán)益所有人同意不得將文件中的內(nèi)容挪作商業(yè)或盈利用途。
- 5. 人人文庫(kù)網(wǎng)僅提供信息存儲(chǔ)空間,僅對(duì)用戶上傳內(nèi)容的表現(xiàn)方式做保護(hù)處理,對(duì)用戶上傳分享的文檔內(nèi)容本身不做任何修改或編輯,并不能對(duì)任何下載內(nèi)容負(fù)責(zé)。
- 6. 下載文件中如有侵權(quán)或不適當(dāng)內(nèi)容,請(qǐng)與我們聯(lián)系,我們立即糾正。
- 7. 本站不保證下載資源的準(zhǔn)確性、安全性和完整性, 同時(shí)也不承擔(dān)用戶因使用這些下載資源對(duì)自己和他人造成任何形式的傷害或損失。
最新文檔
- 2025年廣西北海濱海國(guó)家濕地公園管理處聘用人員控制數(shù)招聘?jìng)淇碱}庫(kù)及一套完整答案詳解
- 2025年彌勒市婦幼保健院公開招聘?jìng)淇碱}庫(kù)及1套參考答案詳解
- 2025年成都郫都西匯三九八醫(yī)院公開招聘人員備考題庫(kù)及1套完整答案詳解
- 甘肅省武威三中教育集團(tuán)聯(lián)片教研2024-2025學(xué)年九年級(jí)上學(xué)期期末考試物理試題(含答案)
- 2025年上海第九人民醫(yī)院成果轉(zhuǎn)化辦公室招聘辦公室工作人員備考題庫(kù)參考答案詳解
- 滄州市第四醫(yī)院康復(fù)院區(qū)2025年人員招聘?jìng)淇碱}庫(kù)及完整答案詳解1套
- 2025年煙臺(tái)交通集團(tuán)有限公司管理培訓(xùn)生招聘?jìng)淇碱}庫(kù)及參考答案詳解一套
- 2025年鹽城市交通運(yùn)輸局部分直屬單位公開招聘事業(yè)性質(zhì)人員備考題庫(kù)及答案詳解1套
- 2025年嘉興市經(jīng)英人才發(fā)展服務(wù)有限公司城南分公司公開招聘勞務(wù)派遣人員備考題庫(kù)及答案詳解參考
- 極簡(jiǎn)商務(wù)年終總結(jié)匯報(bào)
- 埃斯特維華義制藥有限公司年產(chǎn)35噸4800、25噸4790高級(jí)中間體技改項(xiàng)目環(huán)境影響報(bào)告書
- 魔力寶貝寵物卡片武器物品編碼
- 小學(xué)畢業(yè)班動(dòng)員會(huì)教學(xué)課件
- 汽車坡道玻璃雨棚施工方案
- 護(hù)理質(zhì)量檢查記錄69528
- 盆底肌表面肌電解讀
- 《南州六月荔枝丹》公開課PPT
- 四川省地震災(zāi)區(qū)重大地質(zhì)災(zāi)害治理工程資料全套表格
- 核對(duì)稿-700單元聯(lián)鎖
- 山塘整治工程建設(shè)方案
- 中國(guó)醫(yī)院質(zhì)量安全管理 第4-6部分:醫(yī)療管理 醫(yī)療安全(不良)事件管理 T∕CHAS 10-4-6-2018
評(píng)論
0/150
提交評(píng)論