项目简介

这是一个具备实时联机对局功能的五子棋游戏项目,该项目分为客户端与服务端两部分,客户端页面基于QT框架开发,客户端网络部分采用Windows平台下的C++ socket实现,服务端运行在Linux操作系统下,采用Linux平台下的socket网络编程实现。项目整体基于C/C++完成。

整体效果展示

菜单

可以选择本地游戏或网络游戏两种游戏模式。
界面如下:
在这里插入图片描述

本地游戏

本地游戏界面:
在这里插入图片描述

网络游戏

游戏大厅

选择网络游戏进入游戏大厅,客户端成功连接到服务器后即可匹配对手或创建房间。
游戏大厅界面如下:
在这里插入图片描述
一方创建房间后对手即可进行匹配。
展示房间列表:
在这里插入图片描述
进入房间:
在这里插入图片描述

对局效果

双方准备完毕即可开始对局!
对局效果如下:
在这里插入图片描述

在这里插入图片描述

在这里插入图片描述

部分代码

客户端:

//初始化客户端套接字与目标ip地址与端口
client_net::client_net()
{
    WSAStartup(MAKEWORD(2, 2), &wsadata);
    client_fd = socket(PF_INET, SOCK_STREAM, 0);            //建立tcp连接(*)
    client_addr.sin_family = AF_INET;
    client_addr.sin_addr.s_addr = inet_addr("139.196.163.23");  //你的服务器的公网IP
    client_addr.sin_port = htons(1234);                         //目的端口号
    connected = false;
    connect_thread_running = false;
    received = false;
}

//连接服务器
bool client_net::connect()
{
    //SOCKET fd = get_socket_fd();
    if(isConnected())
        return true;
    connect_thread_running = true;      //正在连接
    client_fd = socket(PF_INET, SOCK_STREAM, 0);        //重新建立套接字 否则重新连接不上
    for(int i = 0; i < 10 && connect_thread_running; i++)
    {
        //尝试连接
        int ret = ::connect(client_fd, (struct sockaddr*)&client_addr, sizeof (client_addr));
        //连接成功并接收服务器数据
        if(ret == 0)
        {
            connected = true;
            received = true;
            connect_thread_running = false;
            qDebug() << "连接服务器成功" << endl;
            _beginthreadex(NULL, 0, recv_msg, this, 0, NULL);
            return true;
        }
        qDebug() << "请求连接中:" << i << endl;
    }
    connect_thread_running = false;
    return false;
}

//接收数据
unsigned WINAPI recv_msg(void *arg)
{
    client_net *net = (client_net*)arg;
    SOCKET fd = net->get_socket_fd();
    char msg[1024];
    while(1)
    {
        memset(msg, 0, sizeof(msg));     //*在循环体内必须初始化,否则套接字字符后有脏数据
        int ret = recv(fd, msg, sizeof(msg), 0);
        //客户端主动断开连接时 由于closesocket(fd) 所以recv必然调用失败
        if(ret < 0)
        {
            qDebug() << "与服务器断开连接" << endl;
            net->disconnect();
            return NULL;
        }
        //接收到服务器端发送的EOF 说明服务器已被关闭
        else if(ret == 0)
        {
            qDebug() << "服务器已关闭..." << endl;
            net->disconnect();
            return NULL;
        }
        qDebug() << "recv msg:" << msg << endl;
        net->msg_handle(msg);           //处理数据(存入消息队列中)
    }
    return NULL;
}

服务端:

void R_signal(int client_fd);//处理客户端刷新战局的请求
void C_signal(char* msg,int fd);//处理客户端创建房间的请求
void E_signal(int client_fd);//处理客户端退出房间的请求
void J_signal(int fd,char* msg);//处理客户端加入房间的请求
void U_signal(int fd);//处理客户端更新对手准备状态的请求

struct client_information
{
	int opponent_fd;//对手的套接字
	bool prepare;//准备状态
    bool master;//是否为房间的创建者
    int room_num;//房间号
	client_information() :opponent_fd(0), prepare(0),room_num(-1),master(false){}
};
struct room_information
{   
    int client_fd;//房间中客人的套接字
    string room_name;//房间的名称
    int master_fd;//房间中主人的套接字
    room_information(string name,int fd):room_name(name),master_fd(fd),client_fd(-1){}
};

map<int,client_information>hash_client;//每一个套接字对应一个客户端信息
map<int,struct sockaddr_in>client_addrs;//每一个套接字对应一个客户端的ip地址等信息
vector<room_information>rooms;//房间
vector<int>client_fds;//所有客户端套接字

ending

本项目服务端程序需运行在具有公网地址的服务器上,客户端开发环境为Qt Creator 4.11.1,Qt版本5.14.2。
本项目源码:网络联机五子棋源码

Logo

更多推荐