好久沒來寫點東西,最近鬼事還真是多,破項目搞的人煩死。帶隊的經理說給我們的要求是日代碼100行(核心代碼),懶了這么久,一下寫起來還真是累啊!
最近來了點勁頭,先寫上練的幾個例子
使用windows套接字的網絡小程序-------------------
1.Socket基本操作
(1)啟動/終止
???? winsock在被調用時以動態鏈接庫的形式實現,所以在它初始化時應首先調用WSAStartup函數進行初始化,同時確定被調用的winsock版本號等。
????//??加載套接字庫
????WORD?wVersionRequested;
????WSADATA?wsaData;
????wVersionRequested?=?MAKEWORD(?1,?1?);
????int?err?=?WSAStartup(?wVersionRequested,?&wsaData?);
????if?(?err?!=?0?)?{
????????/*?Tell?the?user?that?we?could?not?find?a?usable?*/
????????/*?WinSock?DLL.??????????????????????????????????*/
????????return?false;
????}
????if?(?LOBYTE(?wsaData.wVersion?)?!=?1?||
????????HIBYTE(?wsaData.wVersion?)?!=?1?)?{
????????????/*?Tell?the?user?that?we?could?not?find?a?usable?*/
????????????/*?WinSock?DLL.??????????????????????????????????*/
????????????WSACleanup(?);
????????????return?false;?
這里加載了1.1版本的socket。在網絡通信完成后,需要使用函數WSACleanup釋放資源。
(2)創建與綁定
套接字的創建非常簡單,只需要調用socket即可。如下:
??? SOCKET sock = socket(AF_INET, SOCK_STREAM, 0);//流式,TCP
SOCKET sock = socket(AF_INET, SOCK_DGRAM, 0);//數據報,UDP
使用bind函數可以將一個套接字綁定到一個地址上
int bind(SOCKET sock, const struct sockaddr* name, int len);//sockaddr是一個用來表示地
址信息的結構
(3)偵聽,接受連接與連接
listen, accept, connect這三個函數用于建立通信的連接。
int listen(SOCKET sock, int backlog);//scok必須是一個已經綁定但是沒有連接的套接字,
backlog用于設定最大可以等待的連接長度
成功調用listen函數后,就可以接受客戶機的連接了。
SOCKET accept(SOCKET sock, struct sockaddr* addr, int* addrlen);
到此一切就緒,當客戶機想到連接時可以使用connect進行連接。
(4)發送,連接
用于TCP的:
int send(SOCKET sock, const char* buf, int len, int flags);
??? int recv(SOCKET sock, char* buf, int len, int flags);
用于UDP的:
int sendto(SOCKET sock, const char* buf, int len, int flags,
const struct sockaddr* to, int tolen);
??? int recvfrom(SOCKET sock, char* buf, int len, int flags,
struct sockaddr* from, int formlen);
2.示例
兩個win32的控制臺程序,一個TcpSer,一個TcpClient。
為了使用socket需要包含頭文件<Winsock2.h>
TcpSer:
#include?<Winsock2.h>
#include?<iostream>
#include?<string>
using?namespace?std;
void?main()
{
????//加載套接字庫,版本1.1
????WORD?wVersionRequested;
????WSADATA?wsaData;
????int?err;
????wVersionRequested?=?MAKEWORD(?1,?1?);
????err?=?WSAStartup(?wVersionRequested,?&wsaData?);
????if?(?err?!=?0?)?{
????????/*?Tell?the?user?that?we?could?not?find?a?usable?*/
????????/*?WinSock?DLL.??????????????????????????????????*/
????????return;
????}
????if?(?LOBYTE(?wsaData.wVersion?)?!=?1?||
????????HIBYTE(?wsaData.wVersion?)?!=?1?)?{
????????????/*?Tell?the?user?that?we?could?not?find?a?usable?*/
????????????/*?WinSock?DLL.??????????????????????????????????*/
????????????WSACleanup(?);
????????????return;?
????}
????
????//創建套接字
????SOCKET?sockSer?=?socket(AF_INET,?SOCK_STREAM,?0);
??? //地址結構體
????SOCKADDR_IN?addrSer;
????addrSer.sin_addr.S_un.S_addr??=?htonl(INADDR_ANY);
????addrSer.sin_family?=?AF_INET;
????addrSer.sin_port?=?htons(6000);
??? //綁定與監聽
????bind(sockSer,?(SOCKADDR*)&addrSer,?sizeof(SOCKADDR));
????listen(sockSer,?5);
????cout<<"Tcp?Server?Run!"<<endl;
????SOCKADDR_IN?addrClient;
????int?len?=?sizeof(SOCKADDR);
//收到連接請求,創建一個新socket用于保持連接
????SOCKET?sockCon?=?accept(sockSer,?(SOCKADDR*)&addrClient,?&len);
????while(true)
????{
????????char?recBuf[100];
????????recv(sockCon,?recBuf,?100,?0);
????????cout<<"message?form?clinet?:?"<<recBuf<<endl;
????}
??? //清理工作
????closesocket(sockSer);
????WSACleanup();
}
TcpClient:
#include?<Winsock2.h>
#include?<iostream>
#include?<string>
using?namespace?std;
void?main()
{
????//加載套接字庫
????WORD?wVersionRequested;
????WSADATA?wsaData;
????int?err;
????wVersionRequested?=?MAKEWORD(?1,?1?);
????err?=?WSAStartup(?wVersionRequested,?&wsaData?);
????if?(?err?!=?0?)?{
????????/*?Tell?the?user?that?we?could?not?find?a?usable?*/
????????/*?WinSock?DLL.??????????????????????????????????*/
????????return;
????}
????if?(?LOBYTE(?wsaData.wVersion?)?!=?1?||
????????HIBYTE(?wsaData.wVersion?)?!=?1?)?{
????????????/*?Tell?the?user?that?we?could?not?find?a?usable?*/
????????????/*?WinSock?DLL.??????????????????????????????????*/
????????????WSACleanup(?);
????????????return;?
????}
????
????//創建套接字
????SOCKET?sockClient?=?socket(AF_INET,?SOCK_STREAM,?0);
????
????SOCKADDR_IN?addrSer;
????addrSer.sin_addr.S_un.S_addr??=?inet_addr("127.0.0.1");
????addrSer.sin_family?=?AF_INET;
????addrSer.sin_port?=?htons(6000);
????cout<<"enter?your?message:?";
????string?sendBuf;
????while(cin>>sendBuf)
????{
????????if(sendBuf?==?"q" || sendBuf == "Q")
????????????break;
????????//連接服務器
????????connect(sockClient,?(SOCKADDR*)&addrSer,?sizeof(SOCKADDR));
????????send(sockClient,?sendBuf.c_str(),?sendBuf.length()+1,?0);
????????cout<<"enter?your?message:?";
????}
????//清理工作
????closesocket(sockClient);
????WSACleanup();
}
最后還要注意的就是:在VS下編譯時還要在項目屬性>配置屬性>鏈接器>命令行里加入附加選項ws2_32.lib
否則鏈接的時候找不到與socket相關的函數