不平凡軟件,始于2014
不平凡和您談---windows下的C++ socket服務(wù)器
}
1.int make_server_socket(int port) 用于創(chuàng)建服務(wù)端的socket的函數(shù),將在后面進(jìn)行講解。
2.void handleAccept(int socket_fd) 用于處理連接到服務(wù)端的客戶端的函數(shù),將在后面進(jìn)行講解。
3.thread C++11中出現(xiàn)的用于多線程編程,需要#include <thread> ,以前涉及到多線程編程時(shí),在windows中需要使用CreateThread,而在linux中需要用pthread_create函數(shù)
而當(dāng)thread出現(xiàn)后,在代碼層面上,windows和linux就統(tǒng)一了。
thread的構(gòu)造函數(shù),
template<class _Fn,class... _Args>
explicit thread(_Fn&& _Fx, _Args&&... _Ax)
{
//
}
簡單來說第一個(gè)參數(shù)表示函數(shù)的名字,其余的參數(shù)表示第一個(gè)參數(shù)所對應(yīng)函數(shù)的參數(shù),模板中的…用到了C++11中的變長模板這一個(gè)概念。
比如 t=thread(handleAccept,socket_fd)// handleAccept 函數(shù)名字,該函數(shù)有一個(gè)int的參數(shù),socket_fd對應(yīng)該int 參數(shù)
在線程創(chuàng)建完成后,我用t.detach(),將線程與主線程分離開,這樣線程在線程結(jié)束時(shí),就會(huì)清空自動(dòng)該線程所占用的??臻g。并且主線程也可以和支線程一起運(yùn)行,不用等待支線程結(jié)束后才能繼續(xù)執(zhí)行。
而如果我們?nèi)绻褂胻.join();會(huì)導(dǎo)致主線程必須等待所有當(dāng)前的支線程結(jié)束后才可以往下執(zhí)行。這樣就無法同時(shí)處理不同客戶端的請求了
還有要注意的是thread默認(rèn)的joinable值是true,這意味著線程是不會(huì)析構(gòu)的,在重復(fù)對同一對象創(chuàng)建線程時(shí)是會(huì)異常終止的,我們需要使用detach()和join(),將joinable的值改為false
例如
void print()
而如果我們把注釋去掉就可以正常運(yùn)行了,同樣將t.detach()改為t.join()也可以。
4.accept();
accept()函數(shù)在windows下
SOCKET accept(SOCKET s,sockaddr* addr,int* addrlen );
accept函數(shù)的第一個(gè)參數(shù)為服務(wù)器的socket描述字,第二個(gè)參數(shù)為指向struct sockaddr *的指針,用于返回客戶端的協(xié)議地址,第三個(gè)參數(shù)為該協(xié)議地址的長度。如果accpet成功,那么返回一個(gè)socket,代表與返回客戶的TCP連接。
在本程序中
int socket_fd = accept(tcp_socket, nullptr, nullptr);
tcp_socket是我們創(chuàng)建的服務(wù)器的socket描述字,而協(xié)議地址和該協(xié)議地址的長度,我們這里不需要,就設(shè)置為nullptr(nullptr為C++11 新增的用于替代null)
在這里accept函數(shù)是阻塞的,在沒有新連接請求來的情況下,accept一直在這里等,函數(shù)沒有返回,程序也不會(huì)往下運(yùn)行。。
大家可以發(fā)現(xiàn)accept在windows中返回的SOCKET類型,而我們用一個(gè)int型接受返回值。
大家可以在vs2013中發(fā)現(xiàn)
所以SOCKET和int是可以進(jìn)行轉(zhuǎn)換的。
相關(guān)新聞換一組