在另外一邊的客戶端,我們分析一下TCPClientSock的建立過程。
class TCPClientSock: public BaseSock{
private:
sockaddr_in serverSockAddr;
protected:
char* preBuffer;
int preBufferSize;
mutable int preReceivedLength;
public:
TCPClientSock(
const char* server_IP,
unsigned short server_port,
int pre_buffer_size = 32);
virtual ~TCPClientSock();
int TCPReceive() const;
int TCPSend(const char* send_data,
const int& data_length) const;
};
我們看到TCPClientSock的類與TCPServerSock很類似,構造函數(shù)的差別是,TCPClientSock需要提供server端的IP地址和端口號。
TCPClientSock::TCPClientSock(
const char *server_IP,
unsigned short server_port,
int pre_buffer_size):
preBufferSize(pre_buffer_size),
preReceivedLength(0)
{
preBuffer = new char[preBufferSize];
sockFD = socket(PF_INET, SOCK_STREAM, IPPROTO_TCP);
if (sockFD < 0) {
sockClass::error_info("sock() failed.");
}
memset(&serverSockAddr, 0, sizeof(serverSockAddr));
serverSockAddr.sin_family = AF_INET;
serverSockAddr.sin_addr.s_addr = inet_addr(server_IP);
serverSockAddr.sin_port = htons(server_port);
if (connect(sockFD,
(struct sockaddr*)&serverSockAddr,
sizeof(serverSockAddr)) < 0 ) {
sockClass::error_info("connect() failed.");
}
}
TCPClientSock::~TCPClientSock()
{
delete [] preBuffer;
close(sockFD);
}
TCPClientSock通過socket()建立起sockFD,然后指定服務器的serverSockAddr,然后通過connect()向serverSockAddr指定的服務器發(fā)出握手請求。需要說明的是,調用connect()的時候,系統(tǒng)會檢查TCPClientSock的sockFD是否已經綁定了本機的SockAddr,事實上我們也可以通過bind()將本機的IP和指定的端口號綁定在這個sockFD上,但是我們并不關心這個IP地址和端口號(況且很多主機并沒有公網IP,特別在中國),所以通常我們不自己去綁定,這樣系統(tǒng)就會幫我們完成綁定工作,分配一個空閑的端口號作為本機地址的端口號。
這樣TCPClientSock具有來向(本機地址,通常由系統(tǒng)自動完成綁定,也可以指定)和去向(指定的server端地址)的地址信息,所以可以收發(fā)信息。于是,TCPClientSock發(fā)出的第一個數(shù)據(jù)報是發(fā)給server監(jiān)聽socket的握手請求數(shù)據(jù)報,TCPListenSock接收這個數(shù)據(jù)報后,將相關信息傳遞給TCPServerSock建立新的sockFD,我們上一節(jié)講到,這個新的sockFD建立起來之后馬上就向client端返回一個數(shù)據(jù)報:一方面表示接受第一次握手請求,另外一方面發(fā)出第二次握手請求。
收到第二次握手請求后,connect()才會返回,不然就會阻塞,非常“盡力”的去連接server。這個“盡力”的程度跟系統(tǒng)有關,在我的試驗中,windows下很快,就幾秒;而Debian則接近6分鐘!
connect()返回的同時,向server發(fā)出了第三次握手的信息,這個信息是對第二次握手請求的認可。所以,第一次和第二次握手包含著連接的請求;而第二次和第三次握手則包含著對握手請求的認可,他們都是在告訴對方:我知道并同意你連接上我了。
至此,TCP三次握手的概念在socket中完整的實現(xiàn),建立起數(shù)據(jù)流的TCP通信通道。
posted on 2010-06-07 00:46
lf426 閱讀(1855)
評論(1) 編輯 收藏 引用 所屬分類:
SDL入門教程 、
Linux與C++ 、
socket 編程入門教程