我一直在研究一个类似于我之前在此发布的程序https://stackoverflow.com/questions/33989328/converting-linked-list-array-client-server-into-single-array的程序,除了这次我试着让示例代码在这个过程中制作我自己的程序(相同的基本当我得到这个奇怪的错误时,程序但不同的内容)。在调试器中有一点,如果argc!= 2它是一个用法:客户端主机名错误。我运行了几次,发现argc是1.我如何使argc为2而不是1或3?有一个客户端和服务器程序如下:
编辑现在它说拒绝连接
客户端:
#include <sys/types.h>
#include <sys/socket.h>
#include <netinet/in.h>
#include <netdb.h>
#include <stdio.h>
#include <stdlib.h>
#include <string.h>
//define constants
#define SERVER_PORT 6500
#define BUFFER_SIZE 1000
void die(const char*);
void pdie(const char *);
int main (int argc, char *argv[]) {
int sock; // file descriptor (fd) for socket connection
struct sockaddr_in server; // Socket info for server
struct sockaddr_in client; // Socket info about us
int clientLen; // length of client socket struct
struct hostent *hp; // return value from gethostbyname()
char buf[BUFFER_SIZE]; // buffer for message reception from server
int i; // loop counter
if (argc != 2) {
die("Usage: client hostname");
}
for(i = 0; i < 3; i++) {
// Open a socket unbound with type ip/tcp
if ((sock = socket(AF_INET, SOCK_STREAM, 0)) < 0 ) {
pdie("Opening stream socket");
}
puts("created sock");
// Prepare to connect to server
memset((char*)&server, 0, sizeof(server));
server.sin_family = AF_INET;
if ((hp = gethostbyname(argv[1])) == NULL) {
char msg[100];
sprintf(msg, "%s: unknown host\n", argv[1]);
die(msg);
}
puts("prepared to connect to server");
// set sin_addr struct variables
memcpy(&server.sin_addr, hp->h_addr, hp->h_length);
// IP address should be set to that of the machine running the server
server.sin_addr.s_addr = inet_addr("replace with your ip address");
server.sin_port = htons((u_short) SERVER_PORT);
// Try to connect
socklen_t serverLen = sizeof(server);
if (connect(sock, (struct sockaddr *) &server, serverLen) < 0) {
pdie("connecting stream socket");
}
// Determine what port client is using
clientLen = sizeof(client);
if (getsockname(sock, (struct sockaddr *) &client, &clientLen)) {
pdie("Getting socket name");
}
if (clientLen != sizeof(client)) {
die("getsocketname() overwrote name structure");
}
printf("Client socket has port %hu\n", ntohs(client.sin_port));
// Prepare our buffer for a read
memset(buf, 0, sizeof(buf));
char input[80];
// get initial prompt
read(sock, buf, BUFFER_SIZE);
printf("%s", (char*)buf);
// get user action choice and send to server
scanf("%s", input);
write(sock, (void*)input, strlen(input));
// control for translation choice
if (strncmp(input, "t", 1) == 0) {
// get prompt for word to translate
read(sock, buf, BUFFER_SIZE);
printf("%s", (char*)buf);
// get user word and send to server
scanf("%s", input);
write(sock, (void*)input, strlen(input));
memset(buf, 0, sizeof(buf));
// get translation
read(sock, buf, BUFFER_SIZE);
// output result
if(strncmp((char*)buf, "ERROR", 5) == 0) {
printf("%s\n", (char*)buf);
} else {
printf("%s in Japanese is %s\n", input, (char*)buf);
}
}
// control for add to dictionary choice
else if (strncmp(input, "a", 1) == 0) {
// get prompt for eng word
memset(buf, 0, sizeof(buf));
read(sock, buf, BUFFER_SIZE);
// get eng word from user
printf("%s", (char*)buf);
scanf("%s", input);
// send eng word to server
write(sock, (void*)input, strlen(input));
memset(buf, 0, sizeof(buf));
// get prompt for Japanese word
read(sock, buf, BUFFER_SIZE);
printf("%s", (char*)buf);
scanf("%s", input);
// send Japanese word to server
write(sock, (void*)input, strlen(input));
// get result
memset(buf, 0, sizeof(buf));
read(sock, buf, BUFFER_SIZE);
printf("%s\n", (char*)buf);
}
// Close this connection
close(sock);
}// end for loop
exit(0);
}// end main
// Call perror() to figure out what's going on and die
void pdie(const char *mesg) {
perror(mesg);
exit(1);
}
// Print a message and die
void die(const char *mesg) {
fputs(mesg, stderr);
fputc('\n', stderr);
exit(1);
}
和服务器
#define _REENTRANT
#include <stdio.h>
#include <stdlib.h>
#include <sys/types.h>
#include <sys/socket.h>
#include <netinet/in.h>
#include <string.h>
#include <sys/uio.h>
#include <unistd.h>
#include <pthread.h>
// constant declarations
#define TCP_PORT 6500
#define BUFFER_SIZE 1000
// variable declarations
pthread_mutex_t lock;
int serve_count;
// used to store eng word and translation
typedef struct wordpair* wordPairPtr;
struct wordPair
{
char* eng;
char* jap;
wordPairPtr nextPair;
};
typedef struct wordPair wordPair;
// used to store all word pairs in a directory
// implemented as a linked list
struct directory
{
wordPair* dict;
int num_words;
};
typedef struct directory directory;
// function prototypes
void* doKid(void*);
void initializeDirect();
int directAdd(char*, char*);
char* translate(char*);
// global directory variable
directory* d;
main ()
{
// variable declarations
int sockfd;
int newsockfd;
int client;
struct sockaddr_in cli_addr, serv_addr;
pthread_t chld_thr;
initializeDirect();// call function to create directory
puts ("initialized variables");
// build thread attributes
pthread_attr_t attr;
pthread_attr_init(&attr);
pthread_attr_setdetachstate(&attr, PTHREAD_CREATE_DETACHED);
puts("set thread attributes");
if ( (sockfd = socket(AF_INET, SOCK_STREAM, 0)) < 0 )
{
fprintf(stderr, "server: can't open stream socket\n");
exit(0);
}
puts("opened stream socket");
// set serv_addr struct variables
memset((char*) &serv_addr, 0, sizeof(serv_addr));
serv_addr.sin_family = AF_INET;
serv_addr.sin_addr.s_addr = htonl(INADDR_ANY);
serv_addr.sin_port = htons(TCP_PORT);
puts("did serv_addr actions");
if (bind(sockfd, (struct sockaddr *) &serv_addr, sizeof(serv_addr)) < 0 )
{
fprintf(stderr, "server: can't bind local address\n");
exit(0);
}
puts("bound local address");
// set the level of thread concurrency we desire
pthread_setconcurrency(5);
listen(sockfd, 5);
puts("set thread concurrency");
// begin listening for client requests
puts("awaiting requests");
for(;;)
{
client = sizeof(cli_addr);
newsockfd = accept(sockfd, (struct sockaddr*) &cli_addr, &client);
if (newsockfd < 0)
{
fprintf(stderr, "server: accept error\n");
exit(0);
}
// create a new thread to process the incoming request
pthread_create(&chld_thr, &attr, doKid, (void*)newsockfd);
puts("Created thread");
// the server is now free to accept another socket request
}
free(d);
puts("now exiting");
return(0);
}// end main
// allocates memory for directory and stores small set of preloaded words and phrases
void initializeDirect()
{
d = (directory*)malloc(sizeof(directory));
if (d == NULL)
{
exit(1);
}
char *eng[20] = {"good morning", "good afternoon", "good evening", "good-bye",
"good night)", "thank you", "no", "yes",
"I'll go and come back", "I'm home", "mother", "father", "older sister", "older brother", "younger sister", "younger brother", "god", "boy", "girl", "spirit"
};
char *jap[20] = {"ohaiyou", "konnichiwa", "konbanwa", "sayonara",
"oyasumi(nasai)", "arigatou", "iie", "hai",
"ittekimasu", "tadaima", "okaasan", "otousan", "oneesan", "oniisan", "imouto", "otouto", "kami", "shoenen", "shoujo", "genki"
};
int i;
for(i = 0; i < 10; i++)
{
directAdd(eng[i], jap[i]);
}
}// end initializeDirect()
// adds a new word pair alphabetically into the directory
int directAdd(char* eng, char* jap)
{
// test for valid arguments
if (eng == NULL || jap == NULL)
{
return (-1);
}
// allocate memory for new wordPair
wordPair *newPair = (wordPair*)malloc(sizeof(wordPair));
if(newPair == NULL)
return(-1);
// assign passed values to new wordPair
newPair->eng = eng;
newPair->jap = jap;
newPair->nextPair = NULL;
// if this is the first wordPair, add it to the front of the linked list
if(d->dict == NULL)
{
d->dict = newPair;
return 0;
}
// otherwise, search directory for correct location for new word pair
wordPair *current = d->dict;
wordPair *previous = NULL;
while(current != NULL && (strcasecmp(current->eng, newPair->eng) < 0))
{
previous = current;
current = current->nextPair;
}
// if the new word is last in the directory, add it there
if(current == NULL)
{
previous->nextPair = newPair;
return 0;
}
// if the english word is already in the directory, return -2
if(strcasecmp(current->eng, newPair->eng) == 0)
{
free(newPair);
return -2;
}
// if the new word is first in the directory, add it there
if(previous == NULL)
{
newPair->nextPair = d->dict;
d->dict = newPair;
return;
}
// if none of the special cases occurred, add the new word
newPair->nextPair = current;
previous->nextPair = newPair;
// advance total count of words
d->num_words++;
// return success
return 0;
}
char* translate(char* eng)
{
// check that our directory is valid
if (d == NULL || d->dict == NULL)
return NULL;
// start searching at the beginning of the directory
wordPair *current = d->dict;
// loop until we find the word or reach the end of the directory
while(current != NULL && strcasecmp(current->eng, eng) < 0)
{
current = current->nextPair;
}
// the word is not in the directory
if(current == NULL)
{
return NULL;
}
// we found the word, return the translation
if( strcasecmp(current->eng, eng) == 0)
{
return strdup(current->jap);
}
// there was an error, return null
return NULL;
}// end translate
// this is the routine that is executed from a new thread
void *doKid(void* arg)
{
int mysocfd = (int) arg;
char buf[BUFFER_SIZE];
char *eng;
char *jap;
char *msg;
int i;
// allocate strings
memset(buf, 0, BUFFER_SIZE);
eng = (char*)malloc(sizeof(char[20]));
jap = (char*)malloc(sizeof(char[20]));
msg = (char*)malloc(sizeof(char[100]));
// build and send intro prompt for client
msg = "Would you like to translate or add a word? (t/a): ";
write(mysocfd, (void*)msg, strlen(msg));
// read from the given socket
read(mysocfd, buf, BUFFER_SIZE);
// if the client wants to translate a word
if(strncmp((char*)buf, "t", 1) == 0)
{
// build and send prompt for word to translate
msg = "Enter the English word you would like to translate to jap: ";
write(mysocfd, (void*)msg, strlen(msg));
// receive word
read(mysocfd, buf, BUFFER_SIZE);
strcpy(eng, buf);
// execute translation
char *trans;
trans = (char*)malloc(sizeof(char[20]));
// lock global variable for read
pthread_mutex_lock(&lock);
trans = translate((char*)buf);
pthread_mutex_unlock(&lock);
// if word was not in directory send error msg to client
if (trans == NULL)
{
msg = "ERROR: word is not in the directory.";
write(mysocfd, (void*)msg, strlen(msg));
}
// if word was translated, send result to client
else
{
write(mysocfd, (void*)trans, strlen(trans));
}
}
// if the client wants to add a word
else if (strncmp((char*)buf, "a", 1) == 0)
{
// build and send prompt for english word
msg = "Enter the English word to add: ";
write(mysocfd, (void*)msg, strlen(msg));
// receive word
read(mysocfd, buf, BUFFER_SIZE);
strcpy(eng, buf);
// build and send prompt for jap translation
memset(buf, 0, sizeof(buf));
msg = "Enter the translation to jap: ";
write(mysocfd, (void*)msg, strlen(msg));
// receive translation
memset(buf, 0, sizeof(buf));
read(mysocfd, buf, BUFFER_SIZE);
strcpy(jap, buf);
// lock global variable for word insertion
pthread_mutex_lock(&lock);
int result = directAdd(eng, jap);
pthread_mutex_unlock(&lock);
// if the add to directory was successful, alert client
if (result == 0)
{
msg = "Added to directory";
}
// if the add to directory was unsuccessful send client error msg
else if (result == -2)
{
msg = "Word is already in directory";
}
else
{
msg = "ERROR.";
}
write(mysocfd, (void*)msg, strlen(msg));
}
// if no valid choice was sent by client, exit thread
else
{
close(mysocfd);
pthread_exit(0);
}
printf("Child[%lu]: Done Processing...\n", pthread_self());
// use a mutex to update the global service counter
pthread_mutex_lock(&lock);
serve_count++;
pthread_mutex_unlock(&lock);
printf("Kid thread [%lu]: The total sockets served = %d\n", pthread_self(), serve_count);
// close the socket and exit this thread
close(mysocfd);
pthread_exit(0);
}// end doKid()