今日の私の質問は、ソケットプログラミングに関するものです。私は、クライアントとサーバーを作成するプログラムで作業しています。クライアントは、指定されたコマンドを使用して、サーバーデータベース内のレコードと対話します。私はソケットプログラミングには非常に新しいので、サーバーとクライアントを接続して相互作用させるための初期コードをいくつか与えました。つまり、「停止」コマンドが出されるまで、別のメッセージを受信して送信するためには、コードのどの部分を反復する必要があるのかよく分かりません。それまでは、ユーザーが引き続きサーバーにメッセージを送信できるようにしたいと考えています。ソケットプログラムによるシーケンシャルユーザー入力の受け入れ
(関連する)サーバコード:
void error(char *msg)
{
perror(msg);
exit(1);
}
int main() {
int num = 1;
int del;
int sockfd, newsockfd, portno;
socklen_t clilen;
char buffer[256];
struct sockaddr_in serv_addr, cli_addr;
int n;
/*STEP 1*********************************************/
sockfd = socket(AF_INET, SOCK_STREAM, 0);
/*Make sure opening was successful*/
if (sockfd < 0)
error("ERROR opening socket");
/*STEP 2********************************************
0 out the server address*/
memset((char *) &serv_addr, 0, sizeof(serv_addr));
/*convert argument to int*/
portno = PORTNO;
/*this is always the same for this type of connection*/
serv_addr.sin_family = AF_INET;
/*INADDR_ANY is a macro that will find the current machine IP*/
serv_addr.sin_addr.s_addr = INADDR_ANY;
/*make sure byte order is correct
may be a no-op, but better safe than sorry*/
serv_addr.sin_port = htons(portno);
/*STEP 3********************************************/
if (bind(sockfd, (struct sockaddr *) &serv_addr,
sizeof(serv_addr)) < 0) {
error("ERROR on binding");
}
/*STEP 4********************************************
Open server up for listening, if you don't listen
you won't hear*/
listen(sockfd,5);
/*STEP 5******************************************/
clilen = sizeof(cli_addr);
/*Accept blocks until a connection with
a client is made. Returns a new socket
to communicate with the new connection.
Also receives address data about client*/
/*Communicate************************************/
char *array[20];
do {
newsockfd = accept(sockfd,
(struct sockaddr *) &cli_addr,
&clilen);
if (newsockfd < 0)
error("ERROR on accept");
memset(buffer, 0, 256);
printf("%s", "Enter Message:");
n = read(newsockfd,buffer,255);
printf("I read %d\n",n);
if (n < 0) error("ERROR reading from socket");
printf("Here is the message: %s",buffer);
n = write(newsockfd,"I got your message",18);
if (n < 0) error("ERROR writing to socket");
int i = 0;
char *p = strtok(buffer, " ");
while (p != NULL)
{
array[i++] = p;
p = strtok (NULL, " ");
}
if (strcmp(array[0], "put") == 0) {
insert(&front, array);
puts("PUT COMMAND");
} else if (strcmp(array[0], "get") == 0 && strcmp(array[1], "lname") == 0) {
puts("GET LNAME COMMAND");
} else if (strcmp(array[0], "get") == 0 && strcmp(array[1], "fname") == 0) {
puts("GET FNAME COMMAND");
} else if (strcmp(array[0], "get") == 0 && strcmp(array[1], "SID") == 0) {
puts("GET SID COMMAND");
} else if (strcmp(array[0], "get") == 0 && strcmp(array[1], "GPA") == 0) {
puts("GET GPA COMMAND");
} else if (strcmp(array[0], "delete") == 0 && strcmp(array[1], "SID") == 0) {
puts("DELETE COMMAND");
} else {
printf("%s\n", "Not a valid command.");
}
} while (strcmp(array[0], "stop") != 0);
return 0;
}
(関連)クライアントコード:
#define PORTNO 20321
#include <stdio.h>
#include <stdlib.h>
#include <sys/types.h>
#include <string.h>
#include <sys/socket.h>
#include <netinet/in.h>
#include <netdb.h>
#include <unistd.h>
void error(char *msg)
{
perror(msg);
exit(0);
}
int main(int argc, char *argv[])
{
/*set up ints for socket file descriptor
port number and return of read/write*/
int sockfd, portno, n;
int i;
/*structure for server info*/
struct sockaddr_in serv_addr;
/*used to hold the return of the function
that finds our server address, will
be copied into serv_addr*/
struct hostent *server;
/*for our message*/
char buffer[256];
/*make sure usage is correct*/
if (argc < 2) {
fprintf(stderr,"usage %s hostname\n", argv[0]);
exit(0);
}
/*convert our port number*/
portno = PORTNO;
/*create the socket*/
sockfd = socket(AF_INET, SOCK_STREAM, 0);
/*make sure it was made*/
if (sockfd < 0)
error("ERROR opening socket");
/*gethostbyname takes our host domain name and
resolves it to an address, there is a similar
function, gethostbyaddr that takes an address
and returns the same struct, struct hostent*/
server = gethostbyname(argv[1]);
/*make sure the host exists*/
if (server == NULL) {
fprintf(stderr,"ERROR, no such host\n");
exit(0);
}
/*0 out the server address stuct and set members*/
memset((char *) &serv_addr, 0, sizeof(serv_addr));
serv_addr.sin_family = AF_INET;
/*copy the data returned from gethostbyname
into the server address struct*/
memcpy((char *)server->h_addr_list,
(char *)&serv_addr.sin_addr.s_addr,
server->h_length);
serv_addr.sin_port = htons(portno);
/*Request a connection to the server through the socket we set up
make sure it connected, this function will also do the binding
of our socket and server info*/
if (connect(sockfd,(struct sockaddr*) &serv_addr,sizeof(serv_addr)) < 0) {
error("ERROR connecting");
}
for (i = 0; i < 3; i++) {
printf("Choose an operation: \n 1. put ln,fn,mi,SID,GPA\n 2. get lname\n 3. get fname\n 4. get SID\n 5. get GPA\n 6. delete (SID)\n 7. stop\nChoice: ");
/*Retrieve a message to send from the user*/
memset(buffer, 0, 256);
fgets(buffer,255,stdin);
/*send the message to the socket*/
printf("length is %d\n", (int)strlen(buffer));
n = write(sockfd,buffer,strlen(buffer));
if (n < 0)
error("ERROR writing to socket");
memset(buffer, 0, 256);
/*await an incoming message, read stops all process*/
n = read(sockfd,buffer,255);
if (n < 0)
error("ERROR reading from socket");
printf("%s\n",buffer);
return 0;
}
}
私のサーバーは、私は私のクライアントプログラムを再起動し、別のものを送ることができるよう、正しくメッセージを待っているように見えますサーバーが待機している間、通常どおり受信されます。しかし、それが立つように、それは別のメッセージを求めますが、最初のメッセージのように正しく送受信されません。今のところ、テストとして3回ループするように設定しています。この読み書きループをサーバーに正しく作成するにはどうすればよいですか?