基础教程
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();
}