網(wǎng)絡(luò)進程通信
1.通過網(wǎng)絡(luò)層“ip地址”可以唯一標識網(wǎng)絡(luò)中的主機
2.傳輸層的“協(xié)議+端口”可以唯一標識主機中的應(yīng)用程序
所以通過 ip地址+協(xié)議+端口 就可以確定標識網(wǎng)絡(luò)的進程了易结,網(wǎng)絡(luò)中的進程通信就可以利用這個標志與其它進程進行交互
socket
socket字面意思就是套接字
網(wǎng)絡(luò)中的進程是通過socket來通信的
客戶端和服務(wù)段通信流程圖(借用網(wǎng)上的圖片使用)
image.png
基本是流程就這樣:
服務(wù)器:創(chuàng)建套接字->綁定協(xié)議地址族(ip地址,端口柜候,通信協(xié)議)->監(jiān)聽客戶端排隊的最大連接個數(shù)->等待接收客戶端連接->數(shù)據(jù)交互->關(guān)閉套接字
客戶端:創(chuàng)建套接字-》連接服務(wù)器地址族-》進入數(shù)據(jù)交互-》關(guān)閉套接字
根據(jù)上面的思路搞动,簡單的示例如下:
SeverSocket
#include<stdio.h>
#include<windows.h>
#pragma comment(lib,"ws2_32.lib")
int main(){
//請求協(xié)議版本
WSADATA wsaData;
WSAStartup(MAKEWORD(2, 2), &wsaData);
if (LOBYTE(wsaData.wVersion) != 2 || HIBYTE(wsaData.wVersion) != 2){
printf("請求協(xié)議版本失敗渣刷!\n");
return -1;
}
//創(chuàng)建socket(協(xié)議版本鹦肿,數(shù)據(jù)類型,協(xié)議)
SOCKET serverSocket = socket(AF_INET, SOCK_STREAM, IPPROTO_TCP);
if (serverSocket == -1){
printf("創(chuàng)建socket失敻ú瘛箩溃!\n");
WSACleanup();
return -2;
}
printf("創(chuàng)建socket成功瞭吃!\n");
//創(chuàng)建協(xié)議地址族
SOCKADDR_IN addr = { 0 };
addr.sin_family = AF_INET;//協(xié)議版本
addr.sin_addr.S_un.S_addr = inet_addr("10.10.12.52");//ip地址
addr.sin_port = htons(10010);//端口,建議自定義端口使用10000之后的涣旨,以為之前的端口可能被其他應(yīng)用程序占用
//綁定
int r = bind(serverSocket, (sockaddr*)&addr, sizeof addr);
if (r == -1){
printf("bind失敗!\n");
closesocket(serverSocket);
WSACleanup();
return -2;
}
printf("bind成功歪架!\n");
//監(jiān)聽
r = listen(serverSocket, 10);
if (r == -1){
printf("listen失敗!\n");
closesocket(serverSocket);
WSACleanup();
return -2;
}
printf("listen成功!\n");
//等待客戶端連接 客戶端協(xié)議地址族
SOCKADDR_IN cAddr = { 0 };
int len = sizeof cAddr;
SOCKET clinetSocket = accept(serverSocket, (sockaddr*)&cAddr, &len);
if (clinetSocket == -1){
printf("服務(wù)器宕機了!\n");
//關(guān)閉socket
closesocket(serverSocket);
//清除協(xié)議信息
WSACleanup();
return -2;
}
printf("有客戶端連接到服務(wù)器了:%s!\n", inet_ntoa(cAddr.sin_addr));
//通信
char buff[1024];
while (1){
r = recv(clinetSocket, buff, 1023, NULL);
if (r > 0){
buff[r] = 0;
printf(">>>>%s\n", buff);
}
}
getchar();
//system("pause");
return 0;
}
ClientSocket
#include<stdio.h>
#include<windows.h>
#pragma comment(lib,"ws2_32.lib")
int main(){
//1.請求協(xié)議版本
WSADATA wsaData;
WSAStartup(MAKEWORD(2, 2), &wsaData);
if (LOBYTE(wsaData.wVersion) != 2 || HIBYTE(wsaData.wVersion) != 2){
printf("請求協(xié)議版本失斂蟆牡拇!\n");
return -1;
}
//2.創(chuàng)建socket
SOCKET clientSocket = socket(AF_INET, SOCK_STREAM, IPPROTO_TCP);
if (clientSocket == -1){
printf("創(chuàng)建socket失敗穆律!\n");
WSACleanup();
return -2;
}
printf("創(chuàng)建socket成功惠呼!\n");
//3.創(chuàng)建協(xié)議地址族
SOCKADDR_IN addr = { 0 };
addr.sin_family = AF_INET;
addr.sin_addr.S_un.S_addr = inet_addr("10.10.12.52");
addr.sin_port = htons(10010);
//4.連接服務(wù)器
int r = connect(clientSocket, (sockaddr*)&addr, sizeof addr);
if (r == -1){
printf("連接服務(wù)器失敗峦耘!\n");
return -2;
}
printf("連接服務(wù)器成功剔蹋!\n");
//5.通信
char buff[1024];
while (1){
memset(buff, 0, 1024);
printf("你想說什么:\n");
scanf("%s", buff);
send(clientSocket, buff, strlen(buff), NULL);
}
getchar();
//system("pause");
return 0;
}
運行結(jié)果:
image.png
可以在這個簡單的例子基礎(chǔ)上進行優(yōu)化,實現(xiàn)多玩家的連接服務(wù)器辅髓,進行數(shù)據(jù)交互