基礎教程
https://www.cnblogs.com/lgh1992314/p/6616393.html
各種函數
https://blog.csdn.net/qq_43152052/article/details/93179297
Dev C++調整:
連接器附加: -lwsock32
編譯器附加:-std=c++11 -lpthread
代碼:
server.cpp
#include <thread>
#include<iostream>
#include<Winsock2.h>
#include<stdio.h>
#pragma comment(lib, "ws2_32.lib")
using namespace std;
int len;
SOCKET sockServer; // 服務端 Socket
SOCKADDR_IN addrServer;// 服務端地址
SOCKET sockClient[5]; // 客戶端 Scoket
SOCKADDR_IN addrClient;// 客戶端地址
WSADATA wsaData; // winsock 結構體
WORD wVersionRequested;// winsock 的版本
char sendBuf[5][100]; // 發送至客戶端的字符串0
char recvBuf[5][100]; // 接受客戶端返回的字符串
void fors(int i){
while(1){
// accept 會阻塞進程,直到有客戶端連接上來爲止
sockClient[i] = accept(sockServer, (SOCKADDR *)&addrClient, &len);
// 當客戶端連接上來時, 拼接如下字符串
sprintf(sendBuf[i],"鏈接成功\n",inet_ntoa(addrClient.sin_addr));
cout<<"<#"<<i<<" join "<<inet_ntoa(addrClient.sin_addr) <<">"<<""<<endl;
// 向客戶端發送字符串
send(sockClient[i],sendBuf[i], strlen(sendBuf[i]) + 10, 0);
while(1){
// 獲取客戶端返回的數據
int error=recv(sockClient[i],recvBuf[i], 100, 0);
if(error==-1) {
cout<<"<#"<<i<<" Exit "<<inet_ntoa(addrClient.sin_addr)<<">"<<endl;
break;
}//獲取數據失敗
// 打印客戶端返回的數據
cout<<"<#"<<i<<" Message "<<inet_ntoa(addrClient.sin_addr)<<"> "<<recvBuf[i]<<endl;
}
// 關閉socket
closesocket(sockClient[i]);
}
}
int got(){
char buf[110];
while(1){
scanf("%s",buf);
if(strcmp(buf,"stop")==0){
exit(0);
}
}
}
int main()
{
// 配置 Windows Socket版本
wVersionRequested=MAKEWORD( 2, 2 );
// 初始化 Windows Socket
int err=WSAStartup( wVersionRequested, &wsaData );
if(err!=0)// 啓動錯誤,程序結束
return 0;
if(LOBYTE(wsaData.wVersion) != 2 || HIBYTE( wsaData.wVersion ) != 2 ){// 啓動錯誤,程序結束
WSACleanup();// 終止Winsock 2 DLL (Ws2_32.dll) 的使用
return 0;
}
// 定義服務器端socket
sockServer= socket(AF_INET, SOCK_STREAM, 0);
// 設置服務端 socket
addrServer.sin_addr.S_un.S_addr= htonl(INADDR_ANY); // 本機IP
addrServer.sin_family= AF_INET; // 協議類型是INET
addrServer.sin_port= htons(6000); // 綁定端口6000
// 將服務器端socket綁定在本地端口
bind(sockServer,(SOCKADDR *)&addrServer, sizeof(SOCKADDR));
// Listen 監聽端口
listen(sockServer,1); // 5 爲等待連接數目
printf("Done!\n");
len = sizeof(SOCKADDR);
thread a(fors,0);
thread ab(fors,1);
thread ini(got);
a.join();
ab.join();
ini.join();
}
cli.cpp
#include <Winsock2.h>
#include <thread>
#include <stdio.h>
#pragma comment(lib, "ws2_32.lib")
using namespace std;
int err;
char message[100];
char recvBuf[100];
SOCKET sockClient; // 客戶端 Scoket
SOCKADDR_IN addrServer; // 服務端地址
WSADATA wsaData;
WORD wVersionRequested;
void exits(){
//關閉
closesocket(sockClient);
WSACleanup();
}
void recs(){
while(1){
int err=recv(sockClient,recvBuf, 100, 0);
if(err==-1) return ;
// 打印數據
printf("%s",recvBuf);
}
}
void sends(){
while(1){
scanf("%s",message);
// 發送數據到服務端
err=send(sockClient, message, strlen(message) + 10, 0);
if(err==-1) return ;
}
}
int main() {
atexit(exits);
wVersionRequested = MAKEWORD( 2, 2 );
err = WSAStartup( wVersionRequested, &wsaData );
if(err != 0) {
return 0;
}
if( LOBYTE( wsaData.wVersion ) != 2 || HIBYTE( wsaData.wVersion ) != 2 ) {
// 啓動錯誤,程序結束
WSACleanup();
return 0;
}
// 新建客戶端 scoket
sockClient = socket(AF_INET, SOCK_STREAM, 0);
// 定義要連接的服務端地址
addrServer.sin_addr.S_un.S_addr= inet_addr("127.0.0.1");
// 目標IP (127.0.0.1是本機地址)
addrServer.sin_family = AF_INET; // 協議類型是INET
addrServer.sin_port = htons(6000); // 連接端口1234
// 讓 sockClient 連接到 服務端
int err=connect(sockClient,(SOCKADDR *)&addrServer, sizeof(SOCKADDR));
if(err==-1) printf("exit"),exit(0);
// 從服務端獲取數據
thread rec(recs);thread se(sends);
rec.join();se.join();
}