socket 编程入门教程(一)TCP server 端:7、接收与发送
生活随笔
收集整理的這篇文章主要介紹了
socket 编程入门教程(一)TCP server 端:7、接收与发送
小編覺得挺不錯的,現在分享給大家,幫大家做個參考.
現在,我們通過accept()創建了新的socket,也就是我們類中的數據成員communicationSock,現在,我們就可以通過這個socket進行通訊了。
TCP通訊模型
??????? 在介紹函數之前,我們應該了解一些事實。TCP的Server/Client模型類似這樣:
ServApp——ServSock——Internet——ClntSock——ClntApp
當然,我們這里的socket指的就是用于“通訊”的socket。TCP的server端至少有兩個socket,一個用于監聽,一個用于通訊;TCP的server端可以只有一個socket,這個socket同時“插”在server的兩個socket上。當然,插上listen socket的目的只是為了創建communication socket,創建完備后,listen是可以關閉的。但是,如果這樣,其他的client就無法再連接上server了。
??????? 我們這個模型,是client的socket插在server的communication socket上的示意。這兩個socket,都擁有完整的本地地址信息以及遠程計算機地址信息,所以,這兩個socket以及之間的網絡實際上形成了一條形式上“封閉”的管道。數據包只要從一端進來,就能知道出去的目的地,反之亦然。這正是TCP協議,數據流形式抽象化以及實現。因為不再需要指明“出處”和“去向”,對這樣的socket(實際上是S/C上的socket對)的操作,就如同對本地文件描述符的操作一樣。但是,盡管我們可以使用read()和write(),但是,為了完美的控制,我們最好使用recv()和send()。
recv()和send()
int?send(int?socket,?const?void*?msg,?unsigned?int?msgLength,?int?flags);
int?recv(int?socket,?void*?rcvBuffer,?unsigned?int?bufferLength,?int?flags); 在Linux中的實現為:
#include?<sys/socket.h>
/*?Send?N?bytes?of?BUF?to?socket?FD.??Returns?the?number?sent?or?-1.
???This?function?is?a?cancellation?point?and?therefore?not?marked?with
???__THROW.??*/
extern?ssize_t?send?(int?__fd,?__const?void?*__buf,?size_t?__n,?int?__flags);
/*?Read?N?bytes?into?BUF?from?socket?FD.
???Returns?the?number?read?or?-1?for?errors.
???This?function?is?a?cancellation?point?and?therefore?not?marked?with
???__THROW.??*/
extern?ssize_t?recv?(int?__fd,?void?*__buf,?size_t?__n,?int?__flags); 這兩個函數的第一個參數是用于“通訊”的socket,第二個參數是發送或者接收數據的起始點指針,第三個參數是數據長度,第四個參數是控制符號(默認屬性設置為0就可以了)。失敗時候傳回-1,否則傳回實際發送或者接收數據的大小,返回0往往意味著連接斷開了。
處理echo行為
void?TcpServer::handleEcho()
{
????const?int?BUFFERSIZE?=?32;
????char?buffer[BUFFERSIZE];
????int?recvMsgSize;
????bool?goon?=?true;
????while?(?goon?==?true?)?{
????????if?(?(recvMsgSize?=?recv(communicationSock,?buffer,?BUFFERSIZE,?0))?<?0?)?{
????????????throw?"recv()?failed";
????????}?else?if?(?recvMsgSize?==?0?)?{
????????????goon?=?false;
????????}?else?{
????????????if?(?send(communicationSock,?buffer,?recvMsgSize,?0)?!=?recvMsgSize?)?{
????????????????throw?"send()?failed";
????????????}
????????}
????}
????close(communicationSock);
} 本小節最后要講的函數是close(),它包含在<unistd.h>中
#include?<unistd.h>
/*?Close?the?file?descriptor?FD.
???This?function?is?a?cancellation?point?and?therefore?not?marked?with
???__THROW.??*/
extern?int?close?(int?__fd); 這個函數用于關閉一個文件描述符,自然,也就可以用于關閉socket。
下一小節是完整的源代碼。默認的監聽端口是5000。我們可以通過
$telnet 127.0.0.1 5000
驗證在本機運行的echo server程序。
TCP通訊模型
??????? 在介紹函數之前,我們應該了解一些事實。TCP的Server/Client模型類似這樣:
ServApp——ServSock——Internet——ClntSock——ClntApp
當然,我們這里的socket指的就是用于“通訊”的socket。TCP的server端至少有兩個socket,一個用于監聽,一個用于通訊;TCP的server端可以只有一個socket,這個socket同時“插”在server的兩個socket上。當然,插上listen socket的目的只是為了創建communication socket,創建完備后,listen是可以關閉的。但是,如果這樣,其他的client就無法再連接上server了。
??????? 我們這個模型,是client的socket插在server的communication socket上的示意。這兩個socket,都擁有完整的本地地址信息以及遠程計算機地址信息,所以,這兩個socket以及之間的網絡實際上形成了一條形式上“封閉”的管道。數據包只要從一端進來,就能知道出去的目的地,反之亦然。這正是TCP協議,數據流形式抽象化以及實現。因為不再需要指明“出處”和“去向”,對這樣的socket(實際上是S/C上的socket對)的操作,就如同對本地文件描述符的操作一樣。但是,盡管我們可以使用read()和write(),但是,為了完美的控制,我們最好使用recv()和send()。
recv()和send()
int?send(int?socket,?const?void*?msg,?unsigned?int?msgLength,?int?flags);
int?recv(int?socket,?void*?rcvBuffer,?unsigned?int?bufferLength,?int?flags); 在Linux中的實現為:
#include?<sys/socket.h>
/*?Send?N?bytes?of?BUF?to?socket?FD.??Returns?the?number?sent?or?-1.
???This?function?is?a?cancellation?point?and?therefore?not?marked?with
???__THROW.??*/
extern?ssize_t?send?(int?__fd,?__const?void?*__buf,?size_t?__n,?int?__flags);
/*?Read?N?bytes?into?BUF?from?socket?FD.
???Returns?the?number?read?or?-1?for?errors.
???This?function?is?a?cancellation?point?and?therefore?not?marked?with
???__THROW.??*/
extern?ssize_t?recv?(int?__fd,?void?*__buf,?size_t?__n,?int?__flags); 這兩個函數的第一個參數是用于“通訊”的socket,第二個參數是發送或者接收數據的起始點指針,第三個參數是數據長度,第四個參數是控制符號(默認屬性設置為0就可以了)。失敗時候傳回-1,否則傳回實際發送或者接收數據的大小,返回0往往意味著連接斷開了。
處理echo行為
void?TcpServer::handleEcho()
{
????const?int?BUFFERSIZE?=?32;
????char?buffer[BUFFERSIZE];
????int?recvMsgSize;
????bool?goon?=?true;
????while?(?goon?==?true?)?{
????????if?(?(recvMsgSize?=?recv(communicationSock,?buffer,?BUFFERSIZE,?0))?<?0?)?{
????????????throw?"recv()?failed";
????????}?else?if?(?recvMsgSize?==?0?)?{
????????????goon?=?false;
????????}?else?{
????????????if?(?send(communicationSock,?buffer,?recvMsgSize,?0)?!=?recvMsgSize?)?{
????????????????throw?"send()?failed";
????????????}
????????}
????}
????close(communicationSock);
} 本小節最后要講的函數是close(),它包含在<unistd.h>中
#include?<unistd.h>
/*?Close?the?file?descriptor?FD.
???This?function?is?a?cancellation?point?and?therefore?not?marked?with
???__THROW.??*/
extern?int?close?(int?__fd); 這個函數用于關閉一個文件描述符,自然,也就可以用于關閉socket。
下一小節是完整的源代碼。默認的監聽端口是5000。我們可以通過
$telnet 127.0.0.1 5000
驗證在本機運行的echo server程序。
總結
以上是生活随笔為你收集整理的socket 编程入门教程(一)TCP server 端:7、接收与发送的全部內容,希望文章能夠幫你解決所遇到的問題。
- 上一篇: 电视/PC/手机通吃!《真·三国无双8》
- 下一篇: am335x otg-usb