猜数字游戏要求:
当客户端第一次连上服务器时,服务器产生一个[0,50]的随机数。
客户端从键盘输入一个数字(猜),将其发送给服务器。
服务器判断客户端发来的数字是否刚才产生的数字,然后返回“大”或“小”的比较结果。
客户端根据返回的评判结果继续猜(输入数字),再发选给服务器。
客户端一共有5次猜的机会,若猜中,则服务器返回“SUCCESS!”然后开启再玩一局或者退出。若猜不中,服务器返回“Falledl”然后开启再玩一局或退出。
若退出,服务器和客户端都结束程序。
介绍该版本适用于Windows版本,如果想在Linux中实现应该在顶端添加该代码行:
#include "stdafx.h"
服务器端代码:
#include <stdio.h>
#include <stdlib.h>
#include <time.h>
#include <winsock2.h>
#pragma comment(lib,"ws2_32.lib")
int main(int argc, char* argv[])
{
// 初始化WSA
WORD sockVersion = MAKEWORD(2, 2);
WSADATA wsaData;
if (WSAStartup(sockVersion, &wsaData) != 0)
{
return 0;
}
// 创建套接字
SOCKET slisten = socket(AF_INET, SOCK_STREAM, IPPROTO_TCP);
if (slisten == INVALID_SOCKET)
{
printf("socket error !");
return 0;
}
// 绑定IP和端口
sockaddr_in sin;
sin.sin_family = AF_INET;
sin.sin_port = htons(8888);
sin.sin_addr.s_addr = INADDR_ANY;
if (bind(slisten, (SOCKADDR *)&sin, sizeof(sin)) == SOCKET_ERROR)
{
printf("bind error !");
return 0;
}
// 开始监听
if (listen(slisten, 5) == SOCKET_ERROR)
{
printf("listen error !");
return 0;
}
// 产生随机数
srand((unsigned int)time(NULL));
int num = rand() % 51;
// 循环接收数据
SOCKET sClient;
sockaddr_in remoteAddr;
int nAddrlen = sizeof(remoteAddr);
char recvData[255];
int guessNum, guessCount = 0;
bool success = false;
while (true)
{
// 等待连接
printf("等待连接...\n");
sClient = accept(slisten, (SOCKADDR *)&remoteAddr, &nAddrlen);
if (sClient == INVALID_SOCKET)
{
printf("accept error !");
continue;
}
printf("接受到一个连接:%s \r\n", inet_ntoa(remoteAddr.sin_addr));
// 开始猜数字
while (!success && guessCount < 5)
{
// 接收猜测数字
int ret = recv(sClient, recvData, 255, 0);
if (ret <= 0)
{
break;
}
recvData[ret] = '\0';
guessNum = atoi(recvData);
printf("收到猜测数字:%d\n", guessNum);
// 判断猜测结果
guessCount++;
if (guessNum == num)
{
char *successMsg = "SUCCESS!\n";
send(sClient, successMsg, strlen(successMsg), 0);
success = true;
break;
}
else if (guessNum > num)
{
char *greaterMsg = "大\n";
send(sClient, greaterMsg, strlen(greaterMsg), 0);
}
else
{
char *lessMsg = "小\n";
send(sClient, lessMsg, strlen(lessMsg), 0);
}
}
// 发送最终结果
if (success)
{
printf("猜测成功!\n");
}
else
{
printf("猜测失败!\n");
}
const char *finalMsg = success ? "再玩一局(Y/N)?\n" : "很遗憾,再玩一局(Y/N)?\n";
send(sClient, finalMsg, strlen(finalMsg), 0);
// 等待玩家选择是否再玩一局
int ret = recv(sClient, recvData, 255, 0);
if (ret <= 0)
{
break;
}
recvData[ret] = '\0';
if (recvData[0] == 'N' || recvData[0] == 'n')
{
break;
}
else
{
// 重置游戏
num = rand() % 51;
guessCount = 0;
success = false;
}
}
// 关闭套接字和WSA
closesocket(sClient);
closesocket(slisten);
WSACleanup();
return 0;
}
客户端代码:
#include <WINSOCK2.H>
#include <STDIO.H>
#pragma comment(lib,"ws2_32.lib")
int main(int argc, char* argv[])
{
WORD sockVersion = MAKEWORD(2,2);
WSADATA data;
if(WSAStartup(sockVersion, &data) != 0)
{
return 0;
}
SOCKET sclient = socket(AF_INET, SOCK_STREAM, IPPROTO_TCP);
if(sclient == INVALID_SOCKET)
{
printf("invalid socket !");
return 0;
}
sockaddr_in serAddr;
serAddr.sin_family = AF_INET;
serAddr.sin_port = htons(8888);
serAddr.sin_addr.S_un.S_addr = inet_addr("127.0.0.1");//记得根据ipconfig所显示的ipv4
//进行修改
if (connect(sclient, (sockaddr *)&serAddr, sizeof(serAddr)) == SOCKET_ERROR)
{
printf("connect error !");
closesocket(sclient);
return 0;
}
char * sendData = "你好,TCP服务端,我是客户端!\n";
send(sclient, sendData, strlen(sendData), 0);
//先发后收
char recData[255];
int ret = recv(sclient, recData, 255, 0);
if(ret > 0)
{
recData[ret] = 0x00;
printf(recData);
}
closesocket(sclient);
WSACleanup();
return 0;
}