我对套接字编程比较陌生,所以请多多包涵。
我正在尝试使用具有特定协议(分隔符、“H”、“L”、“O”)的套接字编程来制作一个简单的猜整数游戏。
当客户端用户根本没有输入任何猜测整数时,我不确定为什么客户端重新发送原始空白数据。
以下是 server.c 文件的部分内容:
#include <stdio.h>
#include <stdlib.h>
#include <string.h>
#include <unistd.h>
#include <sys/types.h>
#include <sys/socket.h>
#include <netinet/in.h>
#include <time.h> /* time for randomizer*/
void error(const char *msg)
{
perror(msg);
exit(1);
}
int main(int argc, char *argv[])
{
int sockfd, newsockfd, portno, n;
socklen_t clilen;
char buffer[256];
struct sockaddr_in serv_addr, cli_addr;
int GuessedInteger, integerRandom, serverFlagCorrect;
char charGuess[4], answerServer[1];
char* delimiter = "\\n";
/** initialization of variables **/
serverFlagCorrect = 0;
/** generate random integer from 1 to 100 **/
srand (time(NULL));
integerRandom = (rand() % 100) + 1;
printf("This is the random integer : %d \n", integerRandom);
if (argc < 2) {
fprintf(stderr,"ERROR, no port provided\n");
exit(1);
}
// Creates the socket socket() --> endpoints of sockets
sockfd = socket(AF_INET, SOCK_STREAM, 0);
if (sockfd < 0)
error("ERROR opening socket");
// Creates the socket socket() --> endpoints of sockets
// assign unique new address
bzero((char *) &serv_addr, sizeof(serv_addr));
portno = atoi(argv[1]);
serv_addr.sin_family = AF_INET;
serv_addr.sin_addr.s_addr = INADDR_ANY;
serv_addr.sin_port = htons(portno);
if (bind(sockfd, (struct sockaddr *) &serv_addr,
sizeof(serv_addr)) < 0)
error("ERROR on binding");
// assign unique new address
// wait for a connection
listen(sockfd,1);
// wait for a connection
// accepts the connection
clilen = sizeof(cli_addr);
newsockfd = accept(sockfd,
(struct sockaddr *) &cli_addr,
&clilen);
if (newsockfd < 0)
error("ERROR on accept");
// accepts the connection
while (serverFlagCorrect != 1)
{
// reads the data being received
bzero(buffer,256);
n = read(newsockfd,buffer,255);
if (n < 0) error("ERROR reading from socket");
// reads the data being received
printf("Buffer from client: <%s>\n", buffer);
memcpy(charGuess, buffer, sizeof(charGuess));
printf("Message from client in charGuess: <%s>\n", charGuess);
/* Put if statement here for error out if no \n at the end */
int len = strlen(charGuess);
const char *last_two = &charGuess[len-2];
printf("Last two characters of charGuess: <%s>\n", last_two);
if (strncmp ( last_two, delimiter, 2) )
error (" ERROR Wrong protocol received");
/** process the string to integer for server comparison **/
GuessedInteger = atoi(charGuess);
printf("Guessed Integer : %d \n", GuessedInteger);
/** Server response for comparison**/
if (GuessedInteger > integerRandom)
memcpy(&answerServer, "L", sizeof(answerServer));
else if (GuessedInteger < integerRandom)
memcpy(&answerServer, "H", sizeof(answerServer));
else if (GuessedInteger == integerRandom)
{
serverFlagCorrect = 1;
memcpy(&answerServer, "O", sizeof(answerServer));
}
printf("Value of answerServer: %c\n", *answerServer);
/** Server response for comparison**/
// sends the answer
n = write(newsockfd, answerServer, 1);
if (newsockfd < 0)
error("ERROR on accept");
// sends the answer
// closes what was sent
close(newsockfd);
// closes what was sent
}
//closes the socket if random integer was found
close(sockfd);
return 0;
}
下面是client.c文件:
#include <stdio.h>
#include <stdlib.h>
#include <unistd.h>
#include <string.h>
#include <sys/types.h>
#include <sys/socket.h>
#include <netinet/in.h>
#include <netdb.h>
void error(const char *msg)
{
perror(msg);
exit(0);
}
int main(int argc, char *argv[])
{
int sockfd, portno, n;
struct sockaddr_in serv_addr;
struct hostent *server;
char buffer[1024];
int integerGuess, clientFlagCorrect;
int numberOfTries;
char charGuess[1024], answerServer[1];
char* delimiter = "\\n";
if (argc < 3) {
fprintf(stderr,"usage %s hostname port\n", argv[0]);
exit(0);
}
portno = atoi(argv[2]);
// Creates the socket socket() --> endpoints of sockets
sockfd = socket(AF_INET, SOCK_STREAM, 0);
if (sockfd < 0)
error("ERROR opening socket");
// Creates the socket socket() --> endpoints of sockets
server = gethostbyname(argv[1]);
if (server == NULL) {
fprintf(stderr,"ERROR, no such host\n");
exit(0);
}
// connects to the service in connect()
bzero((char *) &serv_addr, sizeof(serv_addr));
serv_addr.sin_family = AF_INET;
bcopy((char *)server->h_addr,
(char *)&serv_addr.sin_addr.s_addr,
server->h_length);
serv_addr.sin_port = htons(portno);
if (connect(sockfd,(struct sockaddr *) &serv_addr,sizeof(serv_addr)) < 0)
error("ERROR connecting");
// connects to the service
/** initialization of variables **/
clientFlagCorrect = 0;
numberOfTries = 0;
while (clientFlagCorrect != 1)
{
numberOfTries = numberOfTries + 1;
/** initialization of variables **/
integerGuess = 0;
memset(charGuess, 0, sizeof(charGuess));
// ask the user for the guessed number
printf("Guess: ");
bzero(buffer,sizeof(buffer));
fgets(buffer,sizeof(buffer)-1,stdin);
printf("Buffer to be processed : <%s>\n", buffer);
// ask the user for the guessed number
/** process the integer to string and add a delimiter **/
integerGuess = atoi(buffer);
printf("integerGuess : <%d> \n", integerGuess);
sprintf( charGuess, "%d", integerGuess);
strcat( charGuess, delimiter);
printf("String Guess : <%s> \n", charGuess);
memset(buffer,0,sizeof(buffer));
memcpy(buffer, charGuess, sizeof(charGuess));
printf("Buffer to send : <%s>\n",buffer);
/** process the integer to string and add a delimiter **/
// send the string that was processed
n = write(sockfd,buffer,strlen(buffer));
if (n < 0)
error("ERROR writing to socket");
// send the string that was processed
// reads the data being received
bzero(buffer,256);
n = read(sockfd,buffer,255);
if (n < 0)
error("ERROR reading from socket");
// reads the data being received
printf("Buffer received : <%s>\n",buffer);
memcpy(&answerServer, buffer, sizeof(answerServer));
printf ("Value of answerServer : <%c> \n", *answerServer);
/** Client response **/
if (strncmp ( & answerServer[0],"L",sizeof(answerServer)) == 0)
printf("Lower \n");
else if (strncmp ( & answerServer[0],"H",sizeof(answerServer)) == 0)
printf("Higher \n");
else if (strncmp ( & answerServer[0],"O",sizeof(answerServer)) == 0)
{
printf("Correct \n");
clientFlagCorrect = 1;
}
else
error("ERROR Wrong message received");
}
printf ("Tries: %d \n", numberOfTries);
printf("%s\n",buffer);
close(sockfd);
return 0;
}
有什么建议可以解决我尝试修复了半天的这个相当烦人的错误吗?
我想我提到(如果重要的话),我还不会在这里使用 fork。在我没有先使用 fork 拉出这个简单的猜谜游戏之后,我也会做一些类似的具有 fork 功能的事情。
EDIT1:添加了我通过终端获得的内容(抱歉,我认为删除服务器和客户端代码的某些部分并不好):
服务器端:
$ gcc -Wall -o server server.c
$ ./server 5678
This is the random integer : 66
Buffer from client: <20\n>
Message from client in charGuess: <20\n>
Last two characters of charGuess: <\n>
Guessed Integer : 20
Value of answerServer: H
ERROR reading from socket: Bad file descriptor
$
客户端:
$ ./client3 localhost 5678
Guess: 20
Buffer to be processed : <20
>
integerGuess : <20>
String Guess : <20\n>
Buffer to send : <20\n>
Buffer received : <H>
Value of answerServer : <H>
Higher
Guess:
当来自客户端的用户尚未发送任何内容时,我已经检查它是否已从客户端发送。