クライアントを接続して相互にメッセージを送信できるサーバーをcで作成しようとしています。私は、メッセージを受信し、キューに配置し、ユーザー名がメッセージと一致する場合、サーバーとクライアントの通信(関数dostuff)がそのメッセージを処理するプロセスを持つようにしました。キューを使用してサーバー上のクライアントメッセージを処理しようとしています[C]
if(Front() != NULL)
{
strcpy(dest, Front()->dest);
if(strcmp(dest, username) == 0)
{
strcpy(buffer, Front()->text);
Dequeue();
n = write(sock,buffer,strlen(buffer));
if (n < 0) error("ERROR writing to socket");
}
}
実行されることはありません:
#include <stdio.h>
#include <unistd.h>
#include <stdlib.h>
#include <string.h>
#include <sys/types.h>
#include <sys/socket.h>
#include <netinet/in.h>
/******Struct msg*********/
typedef struct msg
{
char dest [64];
char origin[64];
char text [256];
}msg;
/*********Queue*********/
/*Queue - Linked List implementation*/
#include<stdio.h>
#include<stdlib.h>
struct Node {
msg *data;
struct Node* next;
};
struct Node* front = NULL;
struct Node* rear = NULL;
void Enqueue(msg *x) {
struct Node* temp =
(struct Node*)malloc(sizeof(struct Node));
temp->data =x;
temp->next = NULL;
if(front == NULL && rear == NULL){
front = rear = temp;
return;
}
rear->next = temp;
rear = temp;
}
void Dequeue() {
struct Node* temp = front;
if(front == NULL) {
printf("Queue is Empty\n");
return;
}
if(front == rear) {
front = rear = NULL;
}
else {
front = front->next;
}
free(temp);
}
msg *Front() {
if(front == NULL) {
return 0;
}
return front->data;
}
void error(const char *msg)
{
perror(msg);
exit(1);
}
int interpret(char *line, char username[])
{
//printf("Ready to interpret: %s\n",line);
/*
char *command, *arg1 , *arg2,l[64];
msg *message;
strcpy(l,line);
command = strtok(l," ");
if(strcmp(command, "/tell") == 0)
{
printf("The command was vaid!\n");//chegou aqui
printf("Ready to interpret: %s\n",l);
arg1 = strtok(NULL," ");
printf("I got this far!");
arg2 = l + strlen(command) + strlen(arg1) + 2; //somamos dois por causa dos espaços
message = (msg*)malloc(sizeof(msg));
//printf("I got this far!"); nao está a chegar aqui
strcmp(message->dest, arg1);
strcmp(message->origin, username);
strcmp(message->text, arg2);
Enqueue(message);
printf("(%s -> %s) -%s- was placed on the queue",message->origin,message->dest,message->text);
}
else
{
printf("comando inválido");
}
*/
//this is temporary because there is an error with the code above which made the message not be correct
msg *message;
message = (msg*)malloc(sizeof(msg));
strcmp(message->dest, "dest");
strcmp(message->origin, "origin");
strcmp(message->text, "blahblahblah");
Enqueue(message);
return 1;
}
void dostuff (int sock, char username[])
{
int n, pid;
char buffer[256], dest[64];
pid = fork();
while(1)
{
if(pid > 0)
{
bzero(buffer,256);
n = read(sock,buffer,255);
if (n < 0) error("ERROR reading from socket");
printf("Here is the full message: %s\n",buffer);
//n = write(sock,"I got your message!\n",18);
//if (n < 0) error("ERROR writing to socket");
interpret(buffer, username);
}
else
{
sleep(1);
if(Front() != NULL)
{
strcpy(dest, Front()->dest);
if(strcmp(dest, username) == 0)
{
strcpy(buffer, Front()->text);
Dequeue();
n = write(sock,buffer,strlen(buffer));
if (n < 0) error("ERROR writing to socket");
}
}
}
}
}
int main(int argc, char *argv[])
{
int sockfd, newsockfd, portno, pid , f;
int userCount;
socklen_t clilen;
struct sockaddr_in serv_addr, cli_addr;
if (argc < 2)
{
fprintf(stderr,"ERROR, no port provided\n");
exit(1);
}
sockfd = socket(AF_INET, SOCK_STREAM, 0);
if (sockfd < 0)
error("ERROR opening socket");
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");
listen(sockfd,5);
clilen = sizeof(cli_addr);
userCount = 0;
char dname[64];
f = fork();
while (1)
{
if(f > 0)
{
newsockfd = accept(sockfd,(struct sockaddr *) &cli_addr, &clilen);
if (newsockfd < 0) error("ERROR on accept");
userCount++;
sprintf(dname, "%d", userCount);
pid = fork();
if (pid < 0) error("ERROR on fork");
if (pid == 0)
{
close(sockfd);
dostuff(newsockfd, dname);
exit(0);
}
else close(newsockfd);
}
}
close(sockfd);
return 0;
}
問題は、キューから項目を削除することになっているコードのこの部分があることのようです。 私はこれまでにこのようなことをしたことは一度もなかったので、このアプローチは完全に間違っている可能性があります。誰かが私が何をやっているのかを私に説明したり、別の解決策を提案したりすることができれば、それは素晴らしいことです。
'front'の値を表示するか、デバッガを使用してください。問題は 'front'がNULLだと思われることです。したがって、この機能は決して実行されません。 – Mirakurun
@Mirakurun要素を追加した後にキューが空の場合はメッセージを出力していましたが、その時点でキューは空ではないようですが、それでも条件は満たされません。私はそれがより読みやすくすると思ったので、opのprintステートメントを削除しました。 – Lewis
あなたはタイプミスがあります:すべての 'strcmp'は' interpet'関数本体で 'strcpy'でなければなりません。 – LPs