C语言 TCP 服务器不等待客户端响应?



我的任务是用C语言编写TCP套接字编程编写轮盘游戏。

代码运行良好,直到我接近完成它,并且由于某种未知原因,它停止正常工作,我无法追踪错误。

代码曾经使用简单的recv()调用,所以我尝试制作readn()函数(实际上是从另一篇文章中获取的(,但它并没有解决问题。

我可能忽略了问题,它存在于main()函数的for (int i = 0 ; i < max_round ; i++)循环中。

这是我的服务器:

#include <stdio.h>
#include <unistd.h>
#include <string.h>
#include <stdlib.h>
#include <time.h>
#include <sys/socket.h>
#include <sys/types.h>
#include <netinet/in.h>
int
readn(int f, void *av, int n)
{
char *a;
int m, t;
a = av;
t = 0;
while(t < n){
m = read(f, a+t, n-t);
if(m <= 0){
if(t == 0)
return m;
break;
}
t += m;
}
return t;
}
typedef struct
{
int _count, _bet, _client, _currency;
int _numbers[3];
char *_color;
} Roulette;
int find_element(int searched, int numbers[], int count)
{
for (int i = 0; i < count; i++)
{
if (searched == numbers[i])
return 1;
}
return 0;
}
void Round_Results(Roulette *obj1, Roulette *obj2, const int size)
{
char *lose_msg = "Sajnos nem nyert ebben a korben!n";
char *win_msg = "Gratulalok, ebben a korben nyert!n";
char answer[size];
srand(time(NULL));
int winner_number = rand() % 10;
if ((find_element(winner_number, obj1->_numbers, obj1->_count) == 0) && (find_element(winner_number, obj1->_numbers, obj1->_count) == 0))
{
send(obj1->_client, lose_msg, size, 0);
obj1->_currency = obj1->_currency - obj1->_bet;
printf("%d", obj1->_currency);
sprintf(answer, "%d", obj1->_currency);
send(obj1->_client, answer, size, 0);
send(obj2->_client, lose_msg, size, 0);
obj2->_currency = obj2->_currency - obj2->_bet;
printf("%d", obj2->_currency);
sprintf(answer, "%d", obj2->_currency);
send(obj2->_client, answer, size, 0);
}
else if ((find_element(winner_number, obj1->_numbers, obj1->_count) == 1) && (find_element(winner_number, obj1->_numbers, obj1->_count) == 0))
{
send(obj1->_client, win_msg, size, 0);
obj1->_currency = obj1->_currency + obj1->_bet * (6 / obj1->_count);
printf("%d", obj1->_currency);
sprintf(answer, "%d", obj1->_currency);
send(obj1->_client, answer, size, 0);
send(obj2->_client, lose_msg, size, 0);
obj2->_currency = obj2->_currency - obj2->_bet;
printf("%d", obj2->_currency);
sprintf(answer, "%d", obj2->_currency);
send(obj2->_client, answer, size, 0);
}
else if ((find_element(winner_number, obj1->_numbers, obj1->_count) == 0) && (find_element(winner_number, obj1->_numbers, obj1->_count) == 1))
{
send(obj1->_client, lose_msg, size, 0);
obj1->_currency = obj1->_currency - obj1->_bet;
printf("%d", obj1->_currency);
sprintf(answer, "%d", obj1->_currency);
send(obj1->_client, answer, size, 0);
send(obj2->_client, win_msg, size, 0);
obj2->_currency = obj2->_currency + obj2->_bet * (6 / obj2->_count);
printf("%d", obj2->_currency);
sprintf(answer, "%d", obj2->_currency);
send(obj2->_client, answer, size, 0);
}
else if ((find_element(winner_number, obj1->_numbers, obj1->_count) == 1) && (find_element(winner_number, obj1->_numbers, obj1->_count) == 1))
{
send(obj1->_client, win_msg, size, 0);
obj1->_currency = obj1->_currency + obj1->_bet * (6 / obj1->_count);
printf("%d", obj2->_currency);
sprintf(answer, "%d", obj2->_currency);
send(obj1->_client, answer, size, 0);
send(obj2->_client, win_msg, size, 0);
obj2->_currency = obj2->_currency + obj2->_bet * (6 / obj1->_count);
printf("%d", obj2->_currency);
sprintf(answer, "%d", obj2->_currency);
send(obj2->_client, answer, size, 0);
}
}
void Initialize(int client, int count, int numbers[], int bet, char *color, Roulette *obj)
{
obj->_client = client;
obj->_count = count;
obj->_color = color;
obj->_bet = bet;
for (int i = 0; i < count; i++)
obj->_numbers[i] = numbers[i];
}
void Round_Information(int client, const int size, Roulette *obj)
{
char *message = malloc(size);
char *money_msg = "Mennyi zsetonba fogad?n";
char *number_msg = "Melyik szamra fogad?n[0-9]n";
char *count_msg = "Mennyi szamra fogad?n[1-3]n";
char *color_msg = "Milyen szinre fogad?n[black/red]n";
int count = 0;
char *color;
int numbers[3];
int bet;
//Bet
send(client, money_msg, size, 0);
readn(client,message,size);
bet = atoi(message);
//Count
send(client, count_msg, size, 0);
readn(client,message,size);
count = atoi(message);
//Number/Numbers
for (int i = 0; i < count; i++)
{
send(client, number_msg, size, 0);
readn(client,message,size);
numbers[i] = atoi(message);
}
//Color
send(client, color_msg, size, 0);
readn(client,message,size);
color = message;
Initialize(client, count, numbers, bet, color, obj);
free(message);
return 0;
}
int main(int argc, char **argv)
{
if (argc < 2)
{
printf("tul keves argumentum!nusage : ./valami PORT_NRn");
exit(-1);
}
const int size = 50;
int max_round, starting_money;
int flag = 0;
int on = 1;
char *message = malloc(size);
char *round_msg = "Korok szama :n";
char *greeting_msg = "Sikeresen csatlakozott a szerverre!n";
char *waiting_msg = "A masik jatekosra varunk!n";
char *win_msg = "Gratulalok !nMegnyerte a jatekot!n";
char *lose_msg = "Jatek vege !nSajnos nem nyert!n";
Roulette *obj1 = malloc(size);
Roulette *obj2 = malloc(size);
int server_socket = socket(AF_INET, SOCK_STREAM, flag);
if (server_socket < 0)
{
printf("Nem sikerult a socket-et letrehoznin");
exit(-1);
}
struct sockaddr_in server_adress;
server_adress.sin_addr.s_addr = INADDR_ANY;
server_adress.sin_family = AF_INET;
server_adress.sin_port = atoi(argv[1]);
setsockopt(server_socket, SOL_SOCKET, SO_KEEPALIVE, (char *)&on, sizeof(on));
setsockopt(server_socket, SOL_SOCKET, SO_REUSEADDR, (char *)&on, sizeof(on));
int binding_server = bind(server_socket, (struct sockaddr *)&server_adress, sizeof(server_adress));
if (binding_server < 0)
{
printf("nem sikerult bindolni a szervert!n");
exit(-1);
}
listen(server_socket, 2);
int client1 = accept(server_socket, NULL, NULL);
int client2 = accept(server_socket, NULL, NULL);
send(client1, greeting_msg, size, flag);
send(client2, greeting_msg, size, flag);
printf("Milyen hosszu legyen a jatek ? (Hany kor)n");
scanf("%s", message);
max_round = atoi(message);
//Korok szama
send(client1, message, size, flag);
send(client2, message, size, flag);
printf("Mennyi zsetonnal kezdodjon a jatek?n");
scanf("%s", message);
starting_money = atoi(message);
//Kezdo penz
send(client1, message, size, flag);
send(client2, message, size, flag);
obj1->_currency = starting_money;
obj2->_currency = starting_money;
for (int i = 0; i < max_round; i++)
{
Round_Information(client1, size, obj1);
Round_Information(client2, size, obj2);
Round_Results(obj1, obj2, size);                                    
}
if (obj1->_currency > obj2->_currency)
{
send(obj1->_client, win_msg, size, flag);
send(obj2->_client, lose_msg, size, flag);
}
else if (obj1->_currency < obj2->_currency)
{
send(obj2->_client, win_msg, size, flag);
send(obj1->_client, lose_msg, size, flag);
}
else
{
send(obj1->_client, lose_msg, size, flag);
send(obj2->_client, lose_msg, size, flag);
}
close(client1);
close(client2);
close(server_socket);
free(message);
free(obj1);
free(obj2);
return 0;
}

这是客户端:

#include <stdio.h>
#include <unistd.h>
#include <string.h>
#include <stdlib.h>
#include <sys/socket.h>
#include <sys/types.h>
#include <netinet/in.h>
void Round_Information(int client, const int size, int currency)
{
char *message = malloc(size);
char answer[size];
char *black = "black";
char *red = "red";
int count = 0;
memset(answer, 0, size);
//Bet
recv(client, message, size, 0);
if (currency == 0)
{
printf("Game over!nVeszitett!n");
close(client);
}
while (atoi(answer) < 1 || atoi(answer) > currency)
{
if (strcmp(answer, "befejeztem"))
{
close(client);
}
printf("%s", message);
scanf("%s", answer);
}
if (strcmp(answer, "befejeztem"))
{
close(client);
}
send(client, answer, size, 0);
answer[0] = '0';
//Count
recv(client, message, size, 0);
while (atoi(answer) < 1 || atoi(answer) > 3)
{
if (strcmp(answer, "befejeztem"))
{
close(client);
}
printf("%s", message);
scanf("%s", answer);
}
count = atoi(answer);
if (strcmp(answer, "befejeztem"))
{
close(client);
}
send(client, answer, size, 0);
//Number/Numbers
for (int i = 0; i < count; i++)
{
recv(client, message, size, 0);
answer[0] = 'z';
while (atoi(answer) <= 0 || atoi(answer) > 9)
{
if (strcmp(answer, "befejeztem"))
{
close(client);
}
printf("%s", message);
scanf("%s", answer);
}
if (strcmp(answer, "befejeztem"))
{
close(client);
}
send(client, answer, size, 0);
}
//Color
recv(client, message, size, 0);
while ((strcmp(answer, black) != 0) && (strcmp(answer, red) != 0))
{
if (strcmp(answer, "befejeztem"))
{
close(client);
}
printf("%s", message);
scanf("%s", answer);
}
if (strcmp(answer, "befejeztem"))
{
close(client);
}
send(client, answer, size, 0);
free(message);
}
void Round_Results(int client_socket, char *message, const int size, int *currency)
{
recv(client_socket, message, size, 0);
printf("%sn", message);
recv(client_socket, message, size, 0);
(*currency) = atoi(message);
}
int main(int argc, char **argv)
{
if (argc < 2)
{
printf("tul keves argumentum!nusage : ./valami PORT_NRn");
exit(-1);
}
const int size = 50;
int flag = 0;
int max_round, currency;
int on = 1;
char message[size];
int client_socket = socket(AF_INET, SOCK_STREAM, flag);
if (client_socket < 0)
{
printf("Nem sikerult a socketet letrehozni!n");
exit(-1);
}
struct sockaddr_in server_adress;
server_adress.sin_addr.s_addr = INADDR_ANY;
server_adress.sin_family = AF_INET;
server_adress.sin_port = atoi(argv[1]);
setsockopt(client_socket, SOL_SOCKET, SO_KEEPALIVE, (char *)&on, sizeof(on));
setsockopt(client_socket, SOL_SOCKET, SO_REUSEADDR, (char *)&on, sizeof(on));
int connection = connect(client_socket, (struct sockaddr *)&server_adress, sizeof(server_adress));
if (connection < 0)
{
printf("Nem sikerult kapcsolodni a szerverhez!n");
exit(-1);
}
//Sikeres kapcsolodas
int receive = recv(client_socket, message, size, flag);
if (receive < 0)
{
printf("Nem sikerult megkapni az uzenetet!n");
exit(-1);
}
printf("%s", message);
//Korok szama
receive = recv(client_socket, message, size, flag);
if (receive < 0)
{
printf("Nem sikerult megkapni az uzenetet!n");
exit(-1);
}
printf("Korok szama :%sn", message);
max_round = atoi(message);
//Kezdo penz
receive = recv(client_socket, message, size, flag);
if (receive < 0)
{
printf("Nem sikerult megkapni az uzenetet!n");
exit(-1);
}
printf("Jelenlegi zsetonok mennyisege :%sn", message);
currency = atoi(message);
for (int i = 0; i < max_round; i++)
{
Round_Information(client_socket, size, currency);
Round_Results(client_socket, message, size, &currency);
printf("Jelenlegi zseton :%dn", currency);
}
recv(client_socket, message, size, flag);
printf("%sn", message);
close(client_socket);
return 0;
}

这并不容易阅读,因为我不知道输出是什么意思,但我想我发现了你的问题。

if (strcmp(answer, "befejeztem"))
{
close(client);
}

当字符串相等时,strcmp 为 0。这意味着几乎在每种情况下您都会关闭插座。实际上,在第一个循环中,答案为零,这意味着您要立即关闭插座。如果您关闭套接字但服务器尝试发送数据,程序将收到 SIGPIPE 信号,我认为默认处理程序只会中止程序。

尝试将所有这些 if 语句更改为:

if(!strcmp(answer, "befejeztem"))
{
close(client);
}

最新更新