2013-12-14 6 views
0

Задача: Мне нужна помощь с ошибкой в ​​моем коде. Клиент чата работает, когда у меня работает только один клиент, но если я использую больше клиентов. На моем сервере будут отображаться только последние сообщения клиента. мой client.c, похоже, работает с момента его отправки, но по какой-то причине recv() не получает предыдущий клиент send().Чат-клиент в c

Как работает код: Я установил свой сервер и создаю новый поток всякий раз, когда подключается новый клиент. поток обрабатывает сообщения, которые я получаю от клиента, и распечатываю его на экране сервера.

Код:

CLIENT.C

#define _GNU_SOURCE 
#include <stdio.h> 
#include <stdlib.h> 
#include <string.h> 
#include <errno.h> 
#include <netdb.h> 
#include <unistd.h> 
#include <signal.h> 
#include <assert.h> 
#include <sys/types.h> 
#include <sys/socket.h> 
#include <netdb.h> 

int main(int argc, char ** argv){ 

//get port 
//int port = atoi(argv[1]); 
int server_port = atoi(argv[1]); 
char * name =argv[2]; 
int namelength = strlen(name); 



//set up server adress and socket 
int sock = socket(AF_INET,SOCK_STREAM,0); 
struct sockaddr_in server; 
memset(&server, 0, sizeof(server)); 
server.sin_family = AF_INET; 
server.sin_addr.s_addr = inet_addr("127.0.0.1"); 
server.sin_port = htons(server_port); 


//connect 
if (connect(sock, (struct sockaddr *)&server, sizeof(server)) < 0) { 
    perror("connect failed"); 
    exit(1); 
                    } 
//set up client name                  

char * buff = malloc(5000*sizeof(char)); 
//get the chatting 
//char * other_message = malloc(5000*sizeof(char)); 
while(1){ 
    printf("ENTER MESSAGE:\n"); 
    char message[5000]; 
    strcpy(message, name); 
    strcat(message,": "); 
    printf("%s", message); 

    scanf("%[^\n]",buff); 
    getchar(); 
    strcat(message,buff); 

    int sent = send(sock , message , strlen(message) , MSG_DONTWAIT); 
    if (sent == -1) 
     perror("Send error: "); 
    else 
     printf("Sent bytes: %d\n", sent); 

    } 

return 0;   

}

SERVER.C

#define _GNU_SOURCE 
#include <stdio.h> 
#include <stdlib.h> 
#include <string.h> 
#include <errno.h> 
#include <pthread.h> 
#include <netdb.h> 
#include <unistd.h> 
#include <signal.h> 
#include <assert.h> 
#include <sys/types.h> 
#include <sys/socket.h> 
#include <netdb.h> 

pthread_t * threads = NULL; 
int * client_fd = NULL; 
int num_clients; 
int thread_num; 
void * client_handler(void * cl) 
{ 

int * client = (int *)cl; 
char * message = malloc(5000*sizeof(char)); 
printf("Connected: %d\n",*client); 
int byte=1; 
//recieve the message from clients 
while(1) 
{ 
    byte=recv(*client, message , 5000 , 0); 
    if(byte< 0) 
     break; 

    //send message to all other clients 

    printf("%s\n",message); 
    printf("Recieved bytes:%d\n",byte); 
    memset(message, 0, 5000); 


    /*for(i=0;i<num_clients;i++) 
     if(client_fd[i]!=*client) 
      send(*client , message , strlen(message),0);*/ 
} 
printf("finished: %d\n",*client); 
return NULL; 
} 


int main(int argc, char ** argv) 
{ 

//get the port 
int port = atoi(argv[1]); 

//set up socket 
int socket_fd = socket(AF_INET,SOCK_STREAM,0); 
struct sockaddr_in server,client; 
memset(&server, 0, sizeof(server)); 
server.sin_family = AF_INET; 
server.sin_addr.s_addr = INADDR_ANY; 
server.sin_port = htons(port); 

//bind 
if(bind(socket_fd, (struct sockaddr*)&server,sizeof(server)) < 0){ 
    perror("binding error\n"); 
    exit(1); 
                    } 
//listen                  
if(listen(socket_fd, 10) <0){ 
    perror("binding error\n"); 
    exit(1); 
           } 
//accept incoming connectionns 

threads = malloc(10*sizeof(pthread_t)); 
client_fd = malloc(10*sizeof(int)); 
int i=0; 
int c = sizeof(struct sockaddr_in); 
while(1) 
{ 

    int c_fd = accept(socket_fd,(struct sockaddr *)&client, (socklen_t*)&c); 
    if(c_fd < 0) 
     printf("error"); 
    client_fd[i]=c_fd; 
    pthread_create(&threads[i],NULL,client_handler,(void *)(&c_fd)); 
    i++; 
    num_clients=i; 
}  
return 0; 
} 
+6

Вы слышали об отладчике? –

+0

Что значит? – user3103072

+0

@ user3103072 - о, классический ответ. Вы пишете сетевые приложения, но не имеете понятия отладочных инструментов? –

ответ

2
  • строки Отправка C-типа с StrLen(). Не отправляет завершающий нуль. Использовать strlen() + 1

  • Игнорирование значения, возвращаемого recv(). TCP - это потоковый протокол, который передает только байты/октеты. Он не переносит ничего более сложного. recv() может возвращать один байт вашей линии чата, всю вашу линию чата или что-то среднее между ними. Чтобы передать любое сообщение более сложным, чем один байт, вам нужен протокол, и вы должны его обработать. Ваши «линии чата - строки с нулевым завершением», поэтому вам нужно вызвать recv() в цикле и, используя возвращаемое значение, объединить полученные байты, пока не поступит нуль.

  • Попытка напечатать f без строчек с помощью "% s". Вы не должны пытаться распечатывать полученные данные, пока не убедитесь, что получен нуль.

+0

Я удалил все оскорбления. Вы можете вернуть изменение, если хотите. –

+0

@eznme - нет, мне не надоело :) –