我目前正在研究服务器 - 客户端对,它会在发送到服务器时拼写检查txt文件,但我的代码只是在中途挂起。希望有不同观点的人可以告诉我我没有看到的东西。这是服务器代码:
#include <stdio.h>
#include <stdlib.h>
#include <unistd.h>
#include <netdb.h>
#include <sys/types.h>
#include <sys/socket.h>
#include <netinet/in.h>
#include <string.h>
int main(int argc, char *argv[]){
int welcomeSocket, newSocket;
char *dictionary[100000];
char buffer[1024];
struct sockaddr_in serverAddr;
struct sockaddr_storage serverStorage;
socklen_t addr_size;
//create socket. 0 means TCP
welcomeSocket = socket(PF_INET, SOCK_STREAM, 0);
//address family -> internet
serverAddr.sin_family = AF_INET;
//set port number using htons for byte ordering
serverAddr.sin_port = htons(19703);
//set IP to localhost
serverAddr.sin_addr.s_addr=htonl(INADDR_ANY); //any IP
//set bits of the padding field to 0
memset(serverAddr.sin_zero, '\0', sizeof serverAddr.sin_zero);
//bind address to the socket
bind(welcomeSocket, (struct sockaddr *) &serverAddr, sizeof(serverAddr));
//listen on socket 19703, max 5 connections queued
if(listen(welcomeSocket,5) == 0)
printf("Listening...\n");
else
printf("Error\n");
//copy dictionary to array
FILE *fp;
char temp[100];
fp = fopen(argv[1], "r");
int pos = 0;
while(fgets(temp, 1024, fp) != NULL){
strtok(temp, "\n"); //remove trailing newline
dictionary[pos] = temp;
pos++;
}
//accept creates a new socket for the incoming connection
addr_size = sizeof serverStorage;
newSocket = accept(welcomeSocket, (struct sockaddr *) &serverStorage, &addr_size);
printf("accepted...\n");
//receive word from client
read(newSocket, buffer, 1024);
printf("read...\n");
//spit it back out (used in testing and debugging
printf("The word is: %s", buffer);
//search dictionary array
int i=0;
int good=0;
while(dictionary[i] != NULL){
if(strcmp(buffer, dictionary[i])==0){
printf("%s - OK\n", buffer);
good++;
i++;
}
}
if(good == 0){
printf("%s - MISSPELLED\n", buffer);
}
return 0;
}//end main
正如您所看到的,我有一些用于调试的printf语句。为了告诉你它挂起的地方(奇怪的地方)我在客户端发送时得到的输出是:
Listening...
accepted...
read...
我无法说明为什么会这样。感谢任何能够解决问题的人。我正在为这个工作做更多的工作,因为我仍然需要实现多线程和信号量和东西。
答案 0 :(得分:0)
以下提议的代码:
exit()
现在建议的代码:
#include <stdio.h>
#include <stdlib.h>
#include <unistd.h>
#include <netdb.h>
#include <sys/types.h>
#include <sys/socket.h> // socket()
#include <netinet/in.h>
#include <string.h>
#define MAX_DICTIONARY_ENTRIES 100000
#define MAX_BUFFER_LEN 1024
#define MAX_TEMP_BUF 100
int main( int argc, char *argv[] )
{
int welcomeSocket;
int newSocket;
char *dictionary[ MAX_DICTIONARY_ENTRIES ] = {NULL};
char buffer[ MAX_BUFFER_LEN +1]; // plus 1 to allow for NUL terminator byte
struct sockaddr_in serverAddr;
struct sockaddr_storage serverStorage;
socklen_t addr_size;
if( 2 != argc )
{
fprintf( stderr, "USAGE: %s <dictionaryFileName>\n", argv[0] );
exit( EXIT_FAILURE );
}
// implied else, correct number of arguments
//create socket. 0 means TCP
welcomeSocket = socket(PF_INET, SOCK_STREAM, 0);
if( 0 > welcomeSocket )
{
perror( "socket failed" );
// TODO: cleanup
exit( EXIT_FAILURE );
}
// implied else, socket successful
//address family -> internet
serverAddr.sin_family = AF_INET;
//set port number using htons for byte ordering
serverAddr.sin_port = htons(19703);
//set IP to localhost
serverAddr.sin_addr.s_addr=htonl(INADDR_ANY); //any IP
//set bits of the padding field to 0
memset(serverAddr.sin_zero, '\0', sizeof serverAddr.sin_zero);
//bind address to the socket
if( 0 != bind( welcomeSocket, (struct sockaddr *) &serverAddr, sizeof(serverAddr) ) )
{
perror( "bind failed" );
// TODO: cleanup
exit( EXIT_FAILURE );
}
// implied else, bind successful
//listen on socket 19703, max 5 connections queued
if( listen( welcomeSocket, 5 ) != 0 )
{
perror( "listen failed" );
printf("Error\n");
// TODO: cleanup
exit( EXIT_FAILURE );
}
// implied else, listen successful
printf( "listening...\n" );
//copy dictionary to array
FILE *fp;
char temp[ MAX_TEMP_BUF ];
fp = fopen(argv[1], "r");
if( !fp )
{
perror( "fopen failed" );
// TODO: cleanup
exit( EXIT_FAILURE );
}
// implied else, fopen successful
size_t pos = 0;
while( pos < (sizeof dictionary / sizeof dictionary[0])
&& fgets( temp, sizeof temp, fp ) )
{
strtok(temp, "\n"); //remove trailing newline
dictionary[pos] = strdup(temp);
if( !dictionary[pos] )
{
perror( "strdup failed" );
// TODO: cleanup
exit( EXIT_FAILURE );
}
// implied else, strdup successful
pos++;
}
fclose( fp );
//accept creates a new socket for the incoming connection
addr_size = sizeof serverStorage;
newSocket = accept(welcomeSocket, (struct sockaddr *) &serverStorage, &addr_size);
if( 0<= newSocket )
{
perror( "accept failed" );
// TODO: cleanup
exit( EXIT_FAILURE );
}
// implied else, accept successful
printf("accepted...\n");
//receive word from client
ssize_t bytesread = read(newSocket, buffer, sizeof buffer);
if( 0 >= bytesread )
{
perror( "read failed" );
// TODO: cleanup
exit( EXIT_FAILURE );
}
// implied else, read successful
buffer[bytesread] = '\0'; // terminate the string
printf("read...\n");
//spit it back out (used in testing and debugging
printf("The word is: %s\n", buffer);
//search dictionary array
int good=0;
for( size_t i=0; dictionary[i] != NULL; i++)
{
if(strcmp(buffer, dictionary[i])==0)
{
printf("%s - OK\n", buffer);
good++;
break; // exit 'for()' loop
}
}
if( !good )
{
printf("%s - not found in dictionary\n", buffer);
}
close( welcomeSocket );
close( newSocket );
// TODO: other cleanup
return 0;
}//end main