//服務端(以C++作範例) #include"mysocket.h" //匯入標頭檔案:由於mysock標頭檔案本身就有其它檔案,這裡無需匯入 using namespace std; SOCKET s_accept; int main() { cout << "---------------------------服務端---------------------------\n"; cout << "正在啟動...\n"; startup(); cout << "啟動成功!\n"; SOCKET s = createSocket(PF_INET, SOCK_STREAM); //以IPV6協議建立套接字 //填充資訊 SOCKADDR_IN server_addr; server_addr.sin_family = AF_INET;//協議 server_addr.sin_port = htons(8226);//埠,隨便填 server_addr.sin_addr.S_un.S_addr = inet_addr("127.0.0.1"); //ip地址,這裡填服務端裝置上的ip,127.0.0.1是本地ip,不能實現跨裝置互動 if (bind(s, (SOCKADDR*)&server_addr, sizeof(SOCKADDR)) == SOCKET_ERROR) //繫結套接字 { cout << "套接字繫結失敗!\n"; WSACleanup(); return FALSE; } cout << "套接字繫結成功!" << endl; if (listen(s, 1) == SOCKET_ERROR) { //監聽:將服務端轉為被動狀態,接收請求 cout << "監聽失敗!\n"; WSACleanup(); return FALSE; } cout << "設定監聽狀態成功!\n"; sockaddr_in accept_addr; //用來記錄請求連線的套接字資訊 int len = sizeof(SOCKADDR); cout << "等待客戶端發起請求..." << endl; SOCKET t = accept(s, (SOCKADDR*)&accept_addr, &len); //接受連線請求 if (s_accept == SOCKET_ERROR) { cout << "請求錯誤!\n"; WSACleanup(); return FALSE; } cout << "建立連線成功!\n"; char recv_buf[1145], send_buf[4514]; while(1){ //資訊互動部分,可以作改動 myrecv(t, recv_buf); cout << "接收到客戶端資訊:" << recv_buf << endl; cout << "請輸入要傳送的資訊:"; cin >> send_buf; mysend(t, send_buf); } return 0; }
//客戶端 #include"mysocket.h" //標頭檔案 using namespace std; int main() { cout << "-----------------客戶端----------------\n"; startup(); //啟動 //檢測版本號 if (LOBYTE(wsdata.wVersion) != 2 || HIBYTE(wsdata.wHighVersion) != 2) { cout << "版本號與服務端不匹配!" << endl; WSACleanup(); return FALSE; } //填充服務端資訊:這裡填和服務端一樣的就好,不做解釋 SOCKET client = createSocket(PF_INET, SOCK_STREAM); SOCKADDR_IN server_addr; server_addr.sin_family = AF_INET; server_addr.sin_addr.S_un.S_addr = inet_addr("192.168.1.49"); server_addr.sin_port = htons(8226); //傳送連線請求 請求連線伺服器 if (connect(client, (SOCKADDR*)&server_addr, sizeof(SOCKADDR)) == SOCKET_ERROR) { cout << "連線錯誤!" << endl; WSACleanup(); return -1; } cout << "成功連線到伺服器" << endl; char send_buf[1145], recv_buf[4514]; while(100){ cout << "輸入要傳送的資訊:"; cin>>send_buf; mysend(client, send_buf); cout << "等待服務端響應...\n"; myrecv(client, recv_buf); cout << "收到來自服務端的資訊:" << recv_buf << endl; } return 0; }
//mysocket.h #ifndef __MYSOCKET_H__ #define __MYSOCKET_H__ //標頭檔案保護 #include<bits/stdc++.h> #include<winsock.h> #pragma comment(lib,"ws2_32.lib") using namespace std; WSADATA wsdata; void startup(){ //非同步啟動 if (WSAStartup(MAKEWORD(2, 2), &wsdata)) /* ^ ^ 版本號,這裡用的是2.2 | 資料存放處,這裡設成全域性變數 */ { //返回0則成功,否則失敗,報錯 cout << "啟動失敗!\n"; WSACleanup(); exit(0); } } SOCKET createSocket(int af, int type){ /*原函式原型: SOCKET socket(int af, int type, int protocol) ^ ^ ^ 協議 型別(後文) 形式(一般用0) */ SOCKET ret = socket(af, type, 0); if (ret == INVALID_SOCKET) //錯誤返回INVALID_SOCKET { //報錯 cout << "建立套接字失敗!\n"; WSACleanup(); exit(0); } return ret; } void mysend(SOCKET s, const char* buf){ /* 帶報錯的send()函式,原函式原型為 : int send(SOCKET s, const char* buf, int len, int flag) 這裡為了簡化,省略後兩個引數。 函式把buf傳送給s,返回傳送長度 */ int len = send(s, buf, sizeof(buf), 0); if(len < 0) //傳送錯誤 { cout << "資訊傳送失敗!\n"; WSACleanup(); exit(0); } } void myrecv(SOCKET s, char* buf){ /* 帶報錯的recv()函式,其原型為: int recv(SOCKET s, char* buf, int len, int flag) 同樣省略後兩個引數 函式將從s收到的資訊儲存在buf中,返回接收長度 */ int len = recv(s, buf, sizeof(buf), 0); if(len < 0) { cout << "資訊接收失敗!\n"; WSACleanup(); exit(0); } } #endif //別忘了