Код теперь работает нормально, но я хочу задать вам несколько вопросов. Первый: почему сообщения принимаются медленно (около 1 секунды)? (не локально) Второй вопрос: зачем мне функция сна в строке 213? Третий вопрос: почему мне нужно подтверждение от recv в receiveMessage void, чтобы получать все сообщения?
На linux сокете все в порядке.
#include <ctype.h>
#include <stdio.h>
#include <stdlib.h>
#include <WS2tcpip.h>
#pragma comment (lib, "ws2_32.lib")
#define MAXSIZE 1024
#define PORT 13333
#define FINISH_GAME "cmdfinishgame"
#define RESET_GAME "cmdresetgame"
#define CLOSE_SOCKET "cmdclosesocket"
#define CLEAR_CONSOLE "cmdclearconsole"
const char trustedLetters[27] = "abcdefghijklmnopqrstuvwxyz";
SOCKET serverSocket;
SOCKET clientSocket;
char buffer[MAXSIZE];
char usedLetters[27] = "";
int choose;
void setupServer();
void setupClient();
void sendMessage(char * message);
void receiveMessage(char * message);
int setupGameForServer();
int setupGameForClient();
void startGame();
void spectGame();
void getAUXofStr(char * _Src, char * _Dest);
void spaceString(char * _Src, char * _Dest);
void getChar(char *c);
void waitForUserInput();
void replace(char * _Str, char _Which, char _With);
main. c:
#include "main.h"
int main()
{
while (1)
{
system("cls");
printf("----------------------- \n");
printf("[1] Crea una stanza \n");
printf("[2] Entra in una stanza \n");
printf("----------------------- \n\n");
printf("Scelta: ");
scanf("%s", buffer);
printf("\n");
choose = atoi(buffer);
if (choose == 1)
{
//Inizializzo lato server
setupServer();
//Aspetto che qualcuno si connetta
SOCKADDR_IN clientInfo;
int clientSize = sizeof(clientInfo);
clientSocket = accept(serverSocket, (LPSOCKADDR)&clientInfo, &clientSize);
if (clientSocket == INVALID_SOCKET)
{
exit(1);
}
closesocket(serverSocket);
//in
while (setupGameForServer() == 0);
break;
}
else if (choose == 2)
{
//Inizializzo lato client
setupClient();
while (setupGameForClient() == 0);
break;
}
else if (choose == 99)
{
break;
}
}
closesocket(clientSocket);
WSACleanup();
return 0;
}
int setupGameForServer()
{
memset(usedLetters, 0, sizeof(usedLetters));
memset(buffer, 0, sizeof(buffer));
//Inizia nuova partita
while (1)
{
system("cls");
printf("---------------------------- \n");
printf("[1] Inizia nuova partita \n");
printf("[2] Chiudi \n");
printf("---------------------------- \n\n");
printf("Scelta: ");
scanf("%s", buffer);
printf("\n");
choose = atoi(buffer);
if (choose == 1)
{
sendMessage(RESET_GAME);
break;
}
else if (choose == 2)
{
sendMessage(CLOSE_SOCKET);
return 1;
}
else
{
printf("Errore! Inserire un opzione valida! \n\n\n");
waitForUserInput();
}
}
//-------------
//Chi indovina?
while (1)
{
system("cls");
printf("---------------------- \n");
printf("[1] Indovina il server \n");
printf("[2] Indovina il client \n");
printf("---------------------- \n\n");
printf("Scelta: ");
scanf("%s", buffer);
printf("\n");
choose = atoi(buffer);
if (choose == 1)
{
sendMessage("1");
startGame();
}
else if (choose == 2)
{
sendMessage("2");
printf("Inserisci la frase: ");
scanf(" %[^\n]", buffer);
printf("\n");
sendMessage(buffer);
spectGame();
}
else
{
printf("Errore! Inserire un opzione valida! \n\n\n");
waitForUserInput();
continue;
}
break;
}
//-------------
return 0;
}
int setupGameForClient()
{
//
receiveMessage(buffer);
if (strcmp(buffer, RESET_GAME) == 0)
{
memset(usedLetters, 0, sizeof(usedLetters));
memset(buffer, 0, sizeof(buffer));
}
else if (strcmp(buffer, CLOSE_SOCKET) == 0)
{
return 1;
}
Sleep(10);
//printf("OK!"); //wtf?
//
receiveMessage(buffer);
int i = atoi(buffer);
if (i == 1)
{
printf("Inserisci la frase: ");
scanf(" %[^\n]", buffer);
printf("\n");
sendMessage(buffer);
spectGame();
}
else if (i == 2)
{
startGame();
}
return 0;
}
void setupServer()
{
//Inizializzazione winsock
WSADATA wsaData;
WORD version = MAKEWORD(2, 2);
if (WSAStartup(version, &wsaData))
{
exit(1);
}
//Creazione socket
serverSocket = socket(AF_INET, SOCK_STREAM, IPPROTO_TCP);
if (serverSocket == INVALID_SOCKET)
{
exit(1);
}
//Bind dell'ip e della porta
SOCKADDR_IN serverInfo;
serverInfo.sin_family = AF_INET;
serverInfo.sin_addr.s_addr = ADDR_ANY;
serverInfo.sin_port = htons(PORT);
bind(serverSocket, (LPSOCKADDR)&serverInfo, sizeof(serverInfo));
//Messa del socket in ascolto
listen(serverSocket, 1);
}
void setupClient()
{
//Inizializzazione winsock
WSADATA wsaData;
WORD version = MAKEWORD(2, 2);
if (WSAStartup(version, &wsaData))
{
exit(1);
}
//Creazione socket
clientSocket = socket(AF_INET, SOCK_STREAM, IPPROTO_TCP);
if (clientSocket == INVALID_SOCKET)
{
exit(1);
}
//ip
char ip[16];
printf("Inserisci ip: ");
scanf("%s", ip);
printf("\n");
//Mi connetto al server
SOCKADDR_IN clientInfo;
clientInfo.sin_family = AF_INET;
clientInfo.sin_addr.s_addr = inet_addr(ip);
clientInfo.sin_port = htons(PORT);
connect(clientSocket, (LPSOCKADDR)&clientInfo, sizeof(clientInfo));
}
void startGame()
{
receiveMessage(buffer);
char *phrase;
char *phraseAUX;
phrase = (char *)malloc(strlen(buffer) * sizeof(char));
phraseAUX = (char *)malloc(strlen(buffer) * sizeof(char));
memcpy(phrase, buffer, strlen(buffer));
phrase[strlen(buffer)] = '\0';
phraseAUX[strlen(buffer)] = '\0';
getAUXofStr(phrase, phraseAUX);
system("cls");
sendMessage(CLEAR_CONSOLE);
char c;
int flag = 0;
int lives = 5;
while (1)
{
//stampo lo status
spaceString(phraseAUX, buffer);
printf(buffer);
printf("\n");
sendMessage(buffer);
sendMessage("\n");
snprintf(buffer, 10, "%d", lives);
printf("Vite rimaste: ");
printf(buffer);
printf("\n");
sendMessage("Vite rimaste: ");
sendMessage(buffer);
sendMessage("\n");
//Vedo se ho vinto
if (strcmp(phrase, phraseAUX) == 0)
{
printf("Hai vinto! \n");
sendMessage("Hai scelto una parola troppo easy colione! \n");
break;
}
//Vedo se ho perso
if (lives <= 0)
{
printf("Hai perso! La parola era: \"%s\"\n", phrase);
sendMessage("Il tuo amico finocchio ha perso! GGEZ! \n");
break;
}
//Inserimento carattere
printf("Inserisci carattere: ");
getChar(&c);
printf("\n");
system("cls");
sendMessage(CLEAR_CONSOLE);
//Vedo se la lettera è valida
flag = 0;
for (int i = 0; i < strlen(usedLetters); i++)
{
if (tolower(c) == usedLetters[i])
{
printf("Lettera già utilizzata! \n");
sendMessage("Il tuo amico non capisce un cazzo, ha riinserito la stessa lettera! \n");
flag = 1;
break;
}
}
if (flag)
continue;
else
strncat(usedLetters, &c, 1);
//Sostituisco la lettera nella stringa ausiliaria
flag = 0;
for (int i = 0; i < strlen(phrase); i++)
{
if (tolower(c) == tolower(phrase[i]))
{
phraseAUX[i] = phrase[i];
flag = 1;
}
}
if (!flag)
lives -= 1;
}
waitForUserInput();
sendMessage(FINISH_GAME);
printf("\n\n");
}
void spectGame()
{
while (1)
{
receiveMessage(buffer);
if (strcmp(buffer, CLEAR_CONSOLE) == 0)
{
system("cls");
}
else if (strcmp(buffer, FINISH_GAME) == 0)
{
break;
}
else
{
printf("%s", buffer);
}
}
}
void receiveMessage(char *message)
{
int result;
memset(message, 0, sizeof(message));
//u_long mode = 1; // 1 to enable non-blocking socket
//ioctlsocket(clientSocket, FIONREAD, &mode);
result = recv(clientSocket, message, MAXSIZE, 0);
if (result == 0)
{
exit(1);
}
send(clientSocket, "1", 2, 0);
}
void sendMessage(char *message)
{
int result;
char localBuffer[2];
//u_long mode = 1; // 1 to enable non-blocking socket
//ioctlsocket(clientSocket, FIONBIO, &mode);
result = send(clientSocket, message, (int)strlen(message) + 1, 0);
if (result == 0)
{
exit(1);
}
recv(clientSocket, localBuffer, 2, 0);
if (strcmp(localBuffer, "1") != 0) {
waitForUserInput();
exit(1);
}
}
void getChar(char *c)
{
char str[MAXSIZE];
scanf("%s", str);
*c = str[0];
}
void getAUXofStr(char *_Src, char *_Dest)
{
char trustedLetters[] = "abcdefghijklmnopqrstuvwxyz";
int flag = 0;
for (int s1 = 0; s1 < strlen(_Src); s1 += 1)
{
flag = 0;
for (int s2 = 0; s2 < strlen(trustedLetters); s2 += 1)
{
if (tolower(_Src[s1]) == trustedLetters[s2])
{
_Dest[s1] = '_';
flag = 1;
break;
}
}
if (!flag)
_Dest[s1] = _Src[s1];
}
}
void spaceString(char *_Src, char *_Dest)
{
char finalstr[MAXSIZE];
char space = ' ';
ZeroMemory(finalstr, sizeof(finalstr));
for (int s1 = 0; s1 < strlen(_Src); s1 += 1)
{
strncat(finalstr, &_Src[s1], 1);
strncat(finalstr, &space, 1);
}
strcpy(_Dest, finalstr);
}
void waitForUserInput()
{
printf("Premere un tasto per continuare...\n");
fflush(stdin);
getchar();
}