摘要:上一篇文章是對(duì)編程的入門(mén),這次我們基于實(shí)現(xiàn)一個(gè)簡(jiǎn)單的收發(fā)消息的服務(wù)。通過(guò)上面一篇文章,我們已經(jīng)對(duì)于創(chuàng)建套接字的流程有了一定的了解,在這里就不多說(shuō)這些了。第處將讀取到的輸入信息寫(xiě)入緩沖區(qū),從而發(fā)送到服務(wù)端。
上一篇文章是對(duì)socket編程的入門(mén),這次我們基于socket實(shí)現(xiàn)一個(gè)簡(jiǎn)單的收發(fā)消息的服務(wù)。
實(shí)現(xiàn)思路:
先說(shuō)服務(wù)端:
接受客戶端的連接
讀取客戶端發(fā)送過(guò)來(lái)的信息
將接受到信息發(fā)送給客戶端
客戶端:
首先連接到服務(wù)端
讀取用戶輸入
將用戶輸入的信息發(fā)送給服務(wù)端
發(fā)送之后將會(huì)接收到服務(wù)端返回來(lái)的信息
由于PHP沒(méi)有原生的從命令行接收用戶輸入的函數(shù),所以這里通過(guò)以下方式來(lái)實(shí)現(xiàn):
"/dev/stdin",這個(gè)是linux的標(biāo)準(zhǔn)輸入,其實(shí)這個(gè)函數(shù)就是把linux的標(biāo)準(zhǔn)輸入,重定向到我們的后端PHP程序了。然后我們的PHP程序就接收到了用戶的輸入,接著就可以把這個(gè)輸入發(fā)送到回聲服務(wù)程序的服務(wù)端了。
通過(guò)上面一篇文章,我們已經(jīng)對(duì)于創(chuàng)建套接字的流程有了一定的了解,在這里就不多說(shuō)這些了。
接下來(lái)開(kāi)始服務(wù)端的實(shí)現(xiàn):
echo_server.php:
代碼解讀:
第1處:這里直接使用了上一篇文章介紹的stream_socket_server函數(shù),可以一次性的完成socket的創(chuàng)建、綁定以及監(jiān)聽(tīng)。
第2處:開(kāi)始監(jiān)聽(tīng)我們創(chuàng)建的套接字(至于這里為什么加上@,因?yàn)閟tream_socket_accept函數(shù)如果一定時(shí)間內(nèi)沒(méi)有收到客戶端的連接的話,會(huì)報(bào)一個(gè)warning)
第3處:通過(guò)fread函數(shù),讀取輸入緩沖區(qū),一次讀取1024個(gè)字節(jié)
第4處:將讀取到的字符寫(xiě)入輸入緩沖,從而發(fā)送到客戶端。
通過(guò)上面的程序我們已經(jīng)實(shí)現(xiàn)了回聲服務(wù)程序的服務(wù)端。
接下來(lái)我們可以運(yùn)行一下,會(huì)發(fā)現(xiàn)我們的echo_server.php已經(jīng)進(jìn)入阻塞狀態(tài),等待客戶端連接。
接著實(shí)現(xiàn)客戶端:
echo_client.php
代碼解讀:
第1處:調(diào)用我們的重定向標(biāo)準(zhǔn)輸入函數(shù),調(diào)用此函數(shù)之后,如果不輸入任何字符,程序是不會(huì)執(zhí)行到下一行的,因?yàn)檫@里會(huì)被阻塞。
第2處:如果我們輸入了q這個(gè)字符,將跳出while循環(huán),緊接著會(huì)執(zhí)行fclose,關(guān)閉連接。這里要注意一下,客戶端關(guān)閉連接之后,會(huì)向服務(wù)端發(fā)送一個(gè)信號(hào),告訴服務(wù)端我已經(jīng)斷開(kāi)連接了,服務(wù)端接受到之后將關(guān)閉此客戶端的連接。
第3處:將讀取到的輸入信息寫(xiě)入緩沖區(qū),從而發(fā)送到服務(wù)端。
第4處到第5處是要重點(diǎn)講解的內(nèi)容。
此處為什么不直接通過(guò)fread函數(shù)一次性讀取服務(wù)端返回的消息呢?
以下是對(duì)于這個(gè)問(wèn)題的解答:
對(duì)于每一個(gè)socket,都有一個(gè)發(fā)送緩沖區(qū)和接收緩沖區(qū)。如果我們發(fā)送的數(shù)據(jù)足夠大,則可能分為兩次發(fā)送。也就是說(shuō)fwrite之后,我們發(fā)送的字符有可能被分成兩部分發(fā)送了,而服務(wù)端的代碼是在不斷的接收數(shù)據(jù),然后返回?cái)?shù)據(jù)。
所以客戶端可能出現(xiàn)如下情況:發(fā)送一次字符之后,客戶端尚未接收到全部的數(shù)據(jù)就調(diào)用了fread函數(shù),從而打印多次。
所以對(duì)于這個(gè)問(wèn)題最好的解決方法就是,我們客戶端是能夠提前知道要接收的字符大小的,所以這里通過(guò)strlen函數(shù)獲取要接收的數(shù)據(jù)大小,如果不足這個(gè)大小則繼續(xù)讀取,直到滿足條件之后再輸出。
下面是程序運(yùn)行的效果:
以上則是我們的回聲服務(wù)程序,記得自己動(dòng)手練習(xí)哦,眼過(guò)千遍不如手過(guò)一遍!
本人會(huì)持續(xù)分享一些關(guān)于編程以及編程自學(xué)相關(guān)的文章,記錄自己的自學(xué)編程之路。同時(shí)希望自己的分享能夠幫助一些對(duì)編程感興趣以及正在編程道路上的朋友。歡迎大家關(guān)注我的公眾號(hào)「阿毛的Coding之路 」。
文章版權(quán)歸作者所有,未經(jīng)允許請(qǐng)勿轉(zhuǎn)載,若此文章存在違規(guī)行為,您可以聯(lián)系管理員刪除。
轉(zhuǎn)載請(qǐng)注明本文地址:http://specialneedsforspecialkids.com/yun/30838.html
摘要:擁塞控制算法包含三種擁塞控制算法,和。在早期的實(shí)現(xiàn)當(dāng)中,這兩個(gè)擁塞控制算法分別是在發(fā)送端和接收端實(shí)現(xiàn)的。音頻算法音頻算法指的是在發(fā)送端對(duì)發(fā)送信號(hào)依次進(jìn)行回聲消除降噪以及音量均衡操作,它包含三個(gè)算法回聲消除,噪聲抑制和自動(dòng)增益控制。 1、背景 RTC(Real-time Communica...
摘要:文紅點(diǎn)聯(lián)合創(chuàng)始人王宇航我今天分享的主題,是以實(shí)時(shí)連接場(chǎng)景為目標(biāo)的一些技術(shù)架構(gòu)探索。主要是關(guān)于紅點(diǎn)在產(chǎn)品研發(fā)過(guò)程中,我們的技術(shù)選擇,架構(gòu)變化,還有這個(gè)過(guò)程中,我們的一些考慮。紅點(diǎn)的第一個(gè)版本紅點(diǎn)的第一個(gè)版本功能比較簡(jiǎn)單。 showImg(https://segmentfault.com/img/bVrBAw); 文 | 紅點(diǎn)聯(lián)合創(chuàng)始人 王宇航 我今天分享的主題,是以實(shí)時(shí)連接場(chǎng)景為目標(biāo)的一...
摘要:所以這次采用多進(jìn)程的方式來(lái)實(shí)現(xiàn)同時(shí)為多個(gè)客戶端提供服務(wù)。而多進(jìn)程則是通過(guò)創(chuàng)建多個(gè)進(jìn)程來(lái)共同完成一件事。如果是子進(jìn)程的執(zhí)行環(huán)境,則返回。正常情況下,子進(jìn)程是通過(guò)父進(jìn)程創(chuàng)建的。以上則是我們的多進(jìn)程回聲服務(wù)程序。 上次的回聲服務(wù)程序有個(gè)很大的缺點(diǎn),就是只能同時(shí)連接一個(gè)客戶端,這明顯是不合理的。 所以這次采用多進(jìn)程的方式來(lái)實(shí)現(xiàn)同時(shí)為多個(gè)客戶端提供服務(wù)。 以下是最終的效果:showImg(htt...
閱讀 3835·2021-11-24 09:39
閱讀 3752·2021-11-22 12:07
閱讀 1105·2021-11-04 16:10
閱讀 798·2021-09-07 09:59
閱讀 1902·2019-08-30 15:55
閱讀 935·2019-08-30 15:54
閱讀 724·2019-08-29 14:06
閱讀 2474·2019-08-27 10:54