⭐ 欢迎来到虫虫下载站! | 📦 资源下载 📁 资源专辑 ℹ️ 关于我们
⭐ 虫虫下载站

📄 client.c

📁 QT 做的俄罗斯方快 基于LINUX下的
💻 C
字号:
/*网络客户端输入输出代码*/#include <stdio.h>#include <stdlib.h>#include <sys/types.h>#include <sys/socket.h>#include <arpa/inet.h>#include <unistd.h>#include <fcntl.h>#include <errno.h>#include "client.h"#include "xvid.h"#include "block.h"#include "remote.h"#include "native.h"static int client_init(RussiaBlock * rb, void * data);static Player * client_add_player(RussiaBlock * rb);static int client_recv_player_data(RussiaBlock * rb);static void client_send_player_data(RussiaBlock * rb);static int client_exec_misc_cmd(RussiaBlock * rb);static int key_code[6] = {K_LEFT, K_RIGHT, K_DOWN, K_UP, K_SPACE, K_ESCAPE};RBOPS client_rb_ops = {init:                   client_init,add_player:             client_add_player,add_match:              NULL,del_match:              NULL,recv_player_data:       client_recv_player_data,send_player_data:       client_send_player_data,exec_misc_cmd:          client_exec_misc_cmd,};/*返回网络消息的字节大小*/static int msg_sizeof(int msg){    int size = -1;    switch (msg) {    case MSGTYPE_GRADE:        size = MSGSIZE_GRADE;    break;    case MSGTYPE_MATRIX:        size = MSGSIZE_MATRIX;    break;    case MSGTYPE_WINMAP:        size = MSGSIZE_WINMAP;    break;    case MSGTYPE_MATCH:        size = MSGSIZE_READY;    break;    case MSGTYPE_LOSE:        size = MSGSIZE_LOSE;    break;    case MSGTYPE_WIN:        size = MSGSIZE_LOSE;    break;    }    return size;}/*解压下一个方块的位数据*/static void bits_to_matrix(char * buf, Uchar matrix[4][4]){    unsigned short * s = (unsigned short *)buf;    int x, y;    for (y = 0; y < 4; y++) {        for (x = 0; x < 4; x++) {            if (*s & 0x1)                matrix[y][x] = 1;            else                matrix[y][x] = 0;            *s >>= 1;        }    }}/*解压位数据到输出位图*/static void bits_to_win_map(char * buf, Uchar map[BLOCK_MAP_H][BLOCK_MAP_W]){    char * t = buf;    int x, y;        for (y = 0; y < BLOCK_MAP_H; y++) {        for (x = 0; x < BLOCK_MAP_W; x++) {            if (x % 8 == 0 && x != 0)                t++;            if (*t & 0x1)                map[y][x] = 1;            else                map[y][x] = 0;            *t >>= 1;        }        t++;    }}static int get_msg_from_buf(DataBuffer * buf, int * msg, int * id, char * arg){    int len;    if (BUFEMPTY(buf))        return 0;    if (read_data_from_buf(buf, (char *)msg, sizeof(int)) < sizeof(int))        return 0;    if ((len = msg_sizeof(*msg)) < 0) {        CLEARBUF(buf);        return 0;    }    if (read_data_from_buf(buf, (char *)id, sizeof(int)) < sizeof(int))        return 0;    if (len > 0) {        if (read_data_from_buf(buf, arg, len) < len)            return 0;    }    return 1;}static int client_exec_misc_cmd(RussiaBlock * rb){    CliRB * rb_c = (CliRB *)rb->type_data;    IOOPS * io_ops = rb->io_ops;    char buf[MSG_MAXSIZE];    int msg, id;    while (get_msg_from_buf(rb_c->cmd_buf, &msg, &id, buf)) {        Player * player = 0;        if (id == 0)            player = rb->match[0];        else if (id == 1)            player = rb->match[1];        if (!player)            continue;        if (msg == MSGTYPE_WINMAP) {            bits_to_win_map(buf, player->block_map);            io_ops->out_win_map(player, player->block_map);         }        else if (msg == MSGTYPE_GRADE) {            player->grade = *(int *)buf;            io_ops->out_grade(player);        }        else if (msg == MSGTYPE_MATRIX) {            bits_to_matrix(buf, player->next_matrix);            io_ops->out_next_block(player);        }        else if (msg == MSGTYPE_LOSE) {            rb_c->status &= ~CLI_STATUS_MATCH;            rb_c->status &= ~CLI_STATUS_READY;        }        else if (msg == MSGTYPE_WIN) {            rb_c->status &= ~CLI_STATUS_READY;        }        else if (msg == MSGTYPE_MATCH) {            rb_c->status |= CLI_STATUS_MATCH;        }    }}static int recv_data_from_socket(int sockfd, char * buf, int len){    int size;    if ((size = read(sockfd, buf, len)) < 0)        return 0;    return size;}static int recv_remote_data(RussiaBlock * rb){    CliRB * rb_c = (CliRB *)rb->type_data;    char buf[NETBUF_SIZE], * b = buf;    int cmd_size, len;    len = recv_data_from_socket(rb_c->connfd, buf, NETBUF_SIZE);    while (len >= sizeof(int) * 2            && (cmd_size = msg_sizeof(*b)) >= 0            && len - sizeof(int) * 2 >= cmd_size) {        int size;        char * t;        int l = sizeof(int) * 2 + cmd_size;        t = b;        len -= l;        b += l;        while ((size = write_data_to_buf(rb_c->cmd_buf, t, l)) < l) {            if (!rb->rb_ops->exec_misc_cmd(rb))                return 0;            l -= size;            t += size;        }    }    return 1;}static int recv_key_event(CliRB * rb_c){    int cmd[2] = {MSGTYPE_EVENT};    int key;    while ((key = x_key_event()) >= 0) {        if (rb_c->status & CLI_STATUS_READY) {            int i;            for (i = 0; i < EVENT_NUM; i++) {                if (key == rb_c->event[i]) {                    cmd[1] = i;                    write_data_to_buf(rb_c->send_buf, (char *)cmd, sizeof(cmd));                }            }        }        else if (key == K_SPACE) {            int t = MSGTYPE_READY;            write_data_to_buf(rb_c->send_buf, (char *)&t, sizeof(t));            rb_c->status |= CLI_STATUS_READY;        }    }}static int client_recv_player_data(RussiaBlock * rb){    CliRB * rb_c = (CliRB *)rb->type_data;    recv_remote_data(rb);    if (rb_c->status & CLI_STATUS_MATCH)        recv_key_event(rb_c);    return 1;}static void client_send_player_data(RussiaBlock * rb){    CliRB * rb_c = (CliRB *)rb->type_data;    char buf[NETBUF_SIZE];    int len;    if ((len = read_data_from_buf(rb_c->send_buf, buf, NETBUF_SIZE)) > 0)        if (write(rb_c->connfd, buf, len) != len)            fprintf(stderr, "send data fail.\n");}static Player * client_add_player(RussiaBlock * rb){    CliRB * rb_c = (CliRB *)rb->type_data;    NatPlayer * player;    if (!rb->match[0]) {        player = (NatPlayer *)malloc(sizeof(NatPlayer));        player->io_handle = &io_handle_1;        rb->match[0] = (Player *)player;        rb->match[0]->status |= PLAYER_STATUS_WAIT;    }    else if (!rb->match[1]) {        player = (NatPlayer *)malloc(sizeof(NatPlayer));        player->io_handle = &io_handle_2;        rb->match[1] = (Player *)player;        rb->match[1]->status |= PLAYER_STATUS_WAIT;    }    else {        int status = PLAYER_JOIN;        player = 0;        sleep(1);        write(rb_c->connfd, (char *)&status, sizeof(status));        rb->status |= STATUS_ADD_FINISH;    }    return (Player *)player;}static int client_init(RussiaBlock * rb, void * data){    char * ip_addr = (char *)data;    struct sockaddr_in servaddr = {0};    int sockfd;    CliRB * rb_c;    if ((sockfd = socket(AF_INET, SOCK_STREAM, 0)) < 0) {        perror("client");        return 0;    }    servaddr.sin_family = AF_INET;    servaddr.sin_port = htons(9877);    servaddr.sin_addr.s_addr = inet_addr(ip_addr);    if (connect(sockfd, (struct sockaddr *)&servaddr, sizeof(servaddr)) < 0) {        perror("client");        goto close_fd;    }    fcntl(sockfd, F_SETFL, O_NONBLOCK);    rb_c = (CliRB *)malloc(sizeof(CliRB));    rb_c->connfd = sockfd;    rb_c->cmd_buf = (DataBuffer *)malloc_data_buf(CMDBUFSIZE);    rb_c->send_buf = (DataBuffer *)malloc_data_buf(SENDBUFSIZE);    rb_c->event = key_code;    rb->type_data = rb_c;    if (x_init_display() < 0) {        fprintf(stderr, "init display fail.\n");        return 0;    }    if (init_digit() < 0) {        fprintf(stderr, "Cannt init digit.\n");        return 0;    }    return 1;close_fd:    close(sockfd);    return 0;}

⌨️ 快捷键说明

复制代码 Ctrl + C
搜索代码 Ctrl + F
全屏模式 F11
切换主题 Ctrl + Shift + D
显示快捷键 ?
增大字号 Ctrl + =
减小字号 Ctrl + -