/**************************************************************************
* @file : 五子棋服务端main文件
* @version : 1.0
* @author : Qiyue
* @date : 2016/5/22
* @brief : 接收处理客户端信息并将结果发送至对战双方
**************************************************************************/
#include <WinSock2.h>
#include <iostream>
#include <time.h>
using namespace std;
#pragma comment(lib, "ws2_32.lib")
#define SERVER_IP "127.0.0.1"
#define CONNECT_SUCCEED '1'
#define START '2'
#define CANOPERATION '3'// can to operation
#define GIVE_UP '4' // give up
#define WIN '5'
#define LOSE '6'
#define CLOSE "7"
#define LOCATION '8'
#define FINISH 100
#define CONNECT_ERROR 101
static int chess_board[15][15] = { 0 };
/********************************************************
* @brief :初始化客户端socket
* @input :
* @output :
* @return :
* @author : Qiyue
********************************************************/
int Init(SOCKET &sockSer, SOCKADDR_IN &AddrSer, int port);
/********************************************************
* @brief :等待两个客户端连接
* @input :
* @output :
* @return :
* @author : Qiyue
********************************************************/
int WaitConnect(SOCKET &sockSer, SOCKET &sockCli_1, SOCKADDR_IN &AddrCli_1, SOCKET &sockCli_2, SOCKADDR_IN &AddrCli_2);
/********************************************************
* @brief :传递并分析消息
* @input :
* @output :
* @return : socket error 时返回,返回断线的客户端编号
* @author : Qiyue
********************************************************/
int MessagePassing(SOCKET &sockCli_1, SOCKADDR_IN &AddrCli_1, SOCKET &sockCli_2, SOCKADDR_IN &AddrCli_2);
/********************************************************
* @brief :进行消息分析
* @input :
* @output :产生输赢返回 FINISH ,socket error 时返回,返回断线的客户端编号
* @return :
* @author : Qiyue
********************************************************/
int MessageAnalysis(char* buff, SOCKET &sockCli_1, SOCKADDR_IN &AddrCli_1, SOCKET &sockCli_2, SOCKADDR_IN &AddrCli_2, int comefrom);
/********************************************************
* @brief :判断是否产生输赢
* @input :row col 为 0~14
* @output :
* @return : 产生时返回1,没有时返回0
* @author : Qiyue
********************************************************/
int finish(int row, int col);
int main()
{
int port = 6000;
SOCKET sockSer;
SOCKET sockCli_1;
SOCKET sockCli_2;
SOCKADDR_IN AddrSer;
SOCKADDR_IN AddrCli_1;
SOCKADDR_IN AddrCli_2;
while (Init(sockSer, AddrSer, port) == SOCKET_ERROR);//初始化客户端 IP & port
while (WaitConnect(sockSer, sockCli_1, AddrCli_1, sockCli_2, AddrCli_2))
{
int rel = MessagePassing(sockCli_1, AddrCli_1, sockCli_2, AddrCli_2);
//其中一个客户端掉线 关闭两个套接字 通知重连
closesocket(sockCli_1);
closesocket(sockCli_2);
}
return 0;
}
int Init(SOCKET &sockSer, SOCKADDR_IN &AddrSer, int port)
{
WSADATA wsaData;
if (WSAStartup(MAKEWORD(2, 2), &wsaData) != 0)
{
printf("Failed to load Winsock\n");
}
sockSer = socket(AF_INET, SOCK_STREAM, 0);
AddrSer.sin_family = AF_INET;
AddrSer.sin_port = htons(port);
AddrSer.sin_addr.S_un.S_addr = inet_addr(SERVER_IP);
return bind(sockSer, (LPSOCKADDR)&AddrSer, sizeof(SOCKADDR_IN));
}
int WaitConnect(SOCKET &sockSer, SOCKET &sockCli_1, SOCKADDR_IN &AddrCli_1, SOCKET &sockCli_2, SOCKADDR_IN &AddrCli_2)
{
while (1)
{
if (listen(sockSer, 10) == SOCKET_ERROR){
printf("Listen failed:%d\n", WSAGetLastError());
}
break;
}
int len = sizeof(SOCKADDR);
do{
cout << "Waiting for connect\n";
sockCli_1 = accept(sockSer, (SOCKADDR *)&AddrCli_1, &len);
} while (sockCli_1 == SOCKET_ERROR);
char message_1[] = { CONNECT_SUCCEED };
cout << "Accept client IP : " << inet_ntoa(AddrCli_1.sin_addr) << endl;
send(sockCli_1, message_1, sizeof(message_1), 0);
do{
sockCli_2 = accept(sockSer, (SOCKADDR *)&AddrCli_2, &len);
} while (sockCli_2 == SOCKET_ERROR);
cout << "Accept client IP : " << inet_ntoa(AddrCli_2.sin_addr) << endl;
send(sockCli_2, message_1, sizeof(message_1), 0);
return true;
}
int MessagePassing(SOCKET &sockCli_1, SOCKADDR_IN &AddrCli_1, SOCKET &sockCli_2, SOCKADDR_IN &AddrCli_2)
{
char message[] = { CANOPERATION };
char message_2[] = { START };
char buff[1024];
int rel;
srand(time(0));
do{
rel = send(sockCli_1, message_2, sizeof(message_2), 0);
if (rel == SOCKET_ERROR) return 0;
cout << "send message to 1 start" << endl;
rel = send(sockCli_2, message_2, sizeof(message_2), 0);
cout << "send message to 2 start" << endl;
if (rel == SOCKET_ERROR) return 0;
int PlayFirst = 1;// 执先手随机
if (PlayFirst == 1)
{
rel = send(sockCli_1, message, sizeof(message), 0);
if (rel == SOCKET_ERROR) return 0;//发送操作指令
cout << "send message to 1 operation" << endl;
rel = recv(sockCli_1, buff, sizeof(buff), 0);
cout << "recieve message from 1" << endl;
if (rel == 0 || rel == SOCKET_ERROR) return 0;//接收指令
else rel = MessageAnalysis(buff, sockCli_1, AddrCli_1, sockCli_2, AddrCli_2, 1);
if (rel == FINISH) { continue;}
else if (rel == 0){ return 0; }
}
do
{
rel = send(sockCli_2, message, sizeof(message), 0);
if (rel == SOCKET_ERROR) return 0;//发送操作指令
cout << "send message to 2 operation" << endl;
rel = recv(sockCli_2, buff, sizeof(buff), 0);
cout << "receive message from 2 " << endl;
if (rel == 0 || rel == SOCKET_ERROR) return 0;//接收指令
else rel = MessageAnalysis(buff, sockCli_1, AddrCli_1, sockCli_2, AddrCli_2, 2);
if (rel == FINISH) { break; }
else if (rel == 0){ return 0; }
rel = send(sockCli_1, message, sizeof(message), 0);
if (rel == SOCKET_ERROR) return 0;//发送操作指令
cout << "send message to 1 operation" << endl;
rel = recv(sockCli_1, buff, sizeof(buff), 0);
cout << "receive message from 1 " << endl;
if (rel == 0 || rel == SOCKET_ERROR) return 0;//接收指令
else rel = MessageAnalysis(buff, sockCli_1, AddrCli_1, sockCli_2, AddrCli_2, 1);
if (rel == FINISH) { break; }
else if (rel == 0){ return 0; }
} while (1);//当一局分出胜负时跳出循环
} while (1);// 客户端断开连接时直接返回
return true;
}
int MessageAnalysis(char* buff, SOCKET &sockCli_1, SOCKADDR_IN &AddrCli_1, SOCKET &sockCli_2, SOCKADDR_IN &AddrCli_2, int comefrom)
{
char message_1[] = { WIN };
char message_2[] = { LOSE };
char message_3[] = { LOCATION, 0, 0 };
char type = buff[0];
int row, col;
int rel;
cout << "recieve "<<type << "from"<< comefrom<< endl;
switch (type)
{
case GIVE_UP: // give up
if (comefrom == 1)
{
rel = send(sockCli_2, message_1, sizeof(message_1), 0);
if (rel == SOCKET_ERROR) return 0;
return FINISH;
}
else if (comefrom == 2)
{
rel = send(sockCli_2, message_1, sizeof(message_1), 0);
if (rel == SOCKET_ERROR) return 0;
return FINISH;
}
break;
case LOCATION:
row = buff[1];// 0~15
col = buff[2];// 0~15
if (comefrom == 1)
{
chess_board[row - 1][col - 1] = 1;
if (rel = finish(row - 1, col - 1))
{
message_3[1] = row; message_3[2] = col;
rel = send(sockCli_2, message_3, sizeof(message_3), 0);
cout << "send message to 2 location";
if (rel == SOCKET_ERROR) return 0;
rel = send(sockCli_1, message_1, sizeof(message_1), 0);
cout << "send message to 1 win";
if (rel == SOCKET_ERROR) return 0;
rel = send(sockCli_2, message_2, sizeof(message_2), 0);
cout << "send message to 2 lose";
if (rel == SOCKET_ERROR) return 0;
return FINISH;
}
else
{
message_3[1] = row; message_3[2] = col;
rel = send(sockCli_2, message_3, sizeof(message_3), 0);
cout << "send message to 2 location";
if (rel == SOCKET_ERROR) return 0;
}
}
else if
使用socket实现的五子棋游戏
4星 · 超过85%的资源 需积分: 50 13 浏览量
2017-03-02
22:38:49
上传
评论 23
收藏 10KB ZIP 举报
风中之雪
- 粉丝: 5
- 资源: 4
最新资源
- 鸢尾花(iris)数据集
- %E8%A7%86%E9%A2%91%E8%BD%AC%E9%9F%B3%E9%A2%9120240424092849.mp3
- 数据库中的分组查询及数据筛选
- J185-VB一款SOT23封装P-Channel场效应MOS管
- 计算整数各位数字之和,利用java代码实现
- J185-T2B-VB一款SOT23封装P-Channel场效应MOS管
- map20231226Kalmanfilter.ipynb
- J185-T1B-VB一款SOT23封装P-Channel场效应MOS管
- ASME Y14.5-2018 尺寸与公差标注 中文版
- J185-T1B-A-VB一款SOT23封装P-Channel场效应MOS管
资源上传下载、课程学习等过程中有任何疑问或建议,欢迎提出宝贵意见哦~我们会及时处理!
点击此处反馈