问题标题: C++ 多人联机游戏的简单实例

0
8
已解决
薛乘志
薛乘志
初级启示者
初级启示者

支持同一WIFI/有线网下联机

分为 server.cpp 和 client.cpp

先运行server.cpp并进行一系列配置后可以开始

运行client.cpp并输入server.cpp告诉你的本机IP地址,再设置名称即可

 

这玩意是用来给大家做参考的,所以呢内容上 基 本 没 有,就是数据的发送写了一些

 

编译前再这个位置加一个东西

 

server.cpp

#include <bits/stdc++.h>
#include <winsock2.h>
#include <windows.h>
#include <conio.h>
#pragma comment (lib, "ws2_32.lib") //加载DLL文件
using namespace std;
struct player {
    SOCKET sock;
    bool now;
    char name[];
} pl[1005];
int GetLocalIP(char *ip) {
    WSADATA wsaData;
    char name[155];
    PHOSTENT hostinfo;
    if (WSAStartup(MAKEWORD(2, 0), &wsaData) == 0) {
        if (gethostname(name, sizeof(name)) == 0) {
            if ((hostinfo = gethostbyname(name)) != NULL) {
                ip = inet_ntoa(*(struct in_addr *)*hostinfo->h_addr_list);
                printf("本机IP:%s\n", ip);
            }
        }
        WSACleanup();
    }
    return 1;
}
int main() {
    cout << "程序正在初始化...\n";
    //初始化
    WSADATA wsaData;
    WSAStartup( MAKEWORD(2, 2), &wsaData);
    //创建套接字
    SOCKET sock = socket(PF_INET, SOCK_STREAM, IPPROTO_TCP);
    //绑定套接字
    sockaddr_in sockAddr;
    memset(&sockAddr, 0, sizeof(sockAddr));  //每个字节都用0填充
    sockAddr.sin_family = PF_INET;  //使用IPv4地址
    sockAddr.sin_addr.s_addr = inet_addr("127.0.0.1");  //具体的IP地址
    sockAddr.sin_port = htons(1234);  //端口
    bind(sock, (SOCKADDR*)&sockAddr, sizeof(SOCKADDR));
    //进入监听状态
    listen(sock, 20);
    char getip[64] = {0};
    GetLocalIP(getip);
    cout << "设置开始游戏玩家数:";
    int maxplayer, nowplayer = 0;
    cin >> maxplayer;
    cout << "正在等待玩家加入...\n";
    while (1) {
        if (nowplayer == maxplayer) {
            cout << "发送开始指令...\n";
            for (int i = 1; i <= nowplayer; i++) {
                if (pl[i].now == 0) continue;
                send(pl[i].sock, "start", strlen("start") + sizeof(char), NULL);
            }
            Sleep(1000);
            cout << "游戏已经开始\n";
            break;
        }
        SOCKADDR clntAddr;
        int nSize = sizeof(SOCKADDR);
        SOCKET clntSock = accept(sock, (SOCKADDR*)&clntAddr, &nSize);
        char success[105] = "Success!", name[105];
        send(clntSock, success, strlen(success) + sizeof(char), NULL);
        recv(clntSock, name, MAXBYTE, NULL);
        nowplayer++;
        pl[nowplayer].sock = clntSock;
        strcpy(pl[nowplayer].name, name);
        pl[nowplayer].now = 1;
        cout << name << "加入了游戏\n";
    }
    while (1) {
        for (int i = 1; i <= nowplayer; i++) {
            //确认玩家是否在线
            if (pl[i].now == 0) continue;
            char client[MAXBYTE] = {0};
            recv(pl[i].sock, client, MAXBYTE, NULL);
            if (strcmp(client, "left") == 0) {
                cout << pl[i].name << "下线了\n";
                closesocket(pl[i].sock);
                pl[i].now = 0;
                for (int i = 1; i <= nowplayer; i++) {
                    if (pl[i].now == 0) continue;
                    send(pl[i].sock, "left", strlen("left") + sizeof(char), NULL);
                    send(pl[i].sock, pl[i].name, strlen(pl[i].name) + sizeof(char), NULL);
                }
            }
            send(pl[i].sock, "input", strlen("input") + sizeof(char), NULL);
        }
        Sleep(6000);
        int pin[1005] = {}, pt[5] = {};
        for (int i = 1; i <= nowplayer; i++) {
            if (pl[i].now == 0) continue;
            char client[MAXBYTE] = {0};
            recv(pl[i].sock, client, MAXBYTE, NULL);
            if (strcmp(client, "1") == 0) {
                cout << pl[i].name << "出了剪刀\n";
                pin[i] = 1;
                pt[1]++;
            } else if (strcmp(client, "2") == 0) {
                cout << pl[i].name << "出了石头\n";
                pin[i] = 2;
                pt[2]++;
            } else if (strcmp(client, "3") == 0) {
                cout << pl[i].name << "出了布\n";
                pin[i] = 3;
                pt[3]++;
            } else {
                cout << pl[i].name << "没有出\n";
                pin[i] = 0;
                pt[0]++;
            }
        }
    }
    //关闭套接字
    closesocket(sock);
    //终止 DLL 的使用
    WSACleanup();
    system("pause");
    return 0;
}

client.cpp

#include <bits/stdc++.h>
#include <winsock2.h>
#include <windows.h>
#include <conio.h>
#pragma comment(lib, "ws2_32.lib")  ////加载DLL文件
using namespace std;
int main() {
    cout << "程序正在初始化...";
    //初始化
    WSADATA wsaData;
    WSAStartup(MAKEWORD(2, 2), &wsaData);
    //创建套接字
    SOCKET sock = socket(PF_INET, SOCK_STREAM, IPPROTO_TCP);
    //向**发起请求
    sockaddr_in sockAddr;
    memset(&sockAddr, 0, sizeof(sockAddr));  //每个字节都用0填充
    sockAddr.sin_family = PF_INET;
    system("cls");
    cout << "输入加入游戏的IP:";
    char ip[101];
    cin >> ip;
    sockAddr.sin_addr.s_addr = inet_addr(ip);
    sockAddr.sin_port = htons(1234);
    connect(sock, (SOCKADDR*)&sockAddr, sizeof(SOCKADDR));
    //接收**传回的数据
    char server[MAXBYTE] = {0};
    recv(sock, server, MAXBYTE, NULL);
    if (strcmp(server, "Success!") == 0) {
        cout << "成功连接至**!";
        system("cls");
        cout << "输入你在游戏中的名称:";
        char name[105];
        cin >> name;
        send(sock, name, strlen(name) + sizeof(char), NULL);
        system("cls");
        cout << "已经加入游戏,正在等待游戏开始,请不要退出游戏\n";
        while (1) {
            recv(sock, server, MAXBYTE, NULL);
            if (strcmp(server, "start") == 0) {
                cout << "游戏已经开始\n";
                Sleep(1000);
                system("cls");
                while (1) {
                    if (_kbhit()) {
                        char input = getch();
                        if (input == 'Q' || input == 'q') {
                            send(sock, "left", strlen("left") + sizeof(char), NULL);
                            cout << "已经向**发送下线指令\n";
                            closesocket(sock);
                            WSACleanup();
                            system("pause");
                            return 0;
                        }
                    }
                    send(sock, "online", strlen("online") + sizeof(char), NULL);
                    recv(sock, server, MAXBYTE, NULL);
                    if (strcmp(server, "left") == 0) {
                        recv(sock, server, MAXBYTE, NULL);
                        cout << server << "下线了\n";
                    }
                    if (strcmp(server, "input") == 0) {
                        cout << "请输入(1.剪刀 2.石头 3.布):\n";
                        cout << "请在5秒内输入,否则**可能出现BUG\n";
                        char gamein;
                        cin >> gamein;
                        char chu[3] = {gamein, '\0'};
                        send(sock, chu, strlen(chu) + sizeof(char), NULL);
                    }
                }
                return 0;
            }
        }
    } else {
        cout << "连接失败!";
        closesocket(sock);
        WSACleanup();
        system("pause");
        return 0;
    }
    //关闭套接字
    closesocket(sock);
    //终止使用 DLL
    WSACleanup();
    system("pause");
    return 0;
}

 

@沙宸安

你的XACRAFT多人可以做了


1
0
0
0
0
0
0
0
0
0
被禁言 张欣悦
张欣悦
新手光能
新手光能

会报错

  send(pl[i].sock, "start", strlen("start") + sizeof(char), NULL);

这一行

0
我要回答