2012-11-11 64 views
0

我寫了一個服務器,它從客戶端獲取消息並用它的字典中的單詞(我的文件中的字典)對它們進行響應。例如:C++和C中的簡單回顯服務器

Client wrote: cat 
Server got: cat, Server wrote: miauuu! (and client can see the massege 
from server in his window) 

我dict.txt文件看起來像這樣:

cat 
miauuu! 
dog 
raw,raw! 
etc... 

我有一些問題,我的代碼,使我的服務器從客戶得到的消息,但仍然有問題,發送郵件到客戶端...(在我的客戶端窗口中,我無法看到來自服務器的消息)。作爲客戶我使用telnet。有任何想法嗎?我的意思是,我運行我的服務器:./server 9999和telnet:telnet 127.0.0.1 9999並且可以發送消息到服務器(並且服務器可以看到它們),但是在telnet端我不能看到來自服務器的任何消息(也服務器似乎發送一個空字符串(或什麼,我真的不知道))

#include <stdio.h> 
#include <stdlib.h> 
#include <unistd.h> 
#include <string.h> 
#include <netdb.h> 
#include <pthread.h> 
#include <sys/types.h> 
#include <sys/socket.h> 
#include <netinet/in.h> 
#include <arpa/inet.h> 
#include <map> 
#include <string> 
#include <iostream> 
#include <fstream> 
using namespace std; 

map <string, string> dict; 

void* clients_service(void * arg) 
{ 
    int client_fd = *((int*)&arg), buffsize = 1024, bytes_num = 0; 
    char buffer[1024]; 
    char word[1024]; 

    while(1) 
     { 
      if ((bytes_num = read(client_fd, buffer, buffsize)) == -1) 
      { 
       perror("read error"); 
       exit(1); 
      } 
      else if (bytes_num == 0) 
      { 
       fprintf(stdout, "connection closed.\n"); 
       break; 
      } 

      buffer[bytes_num] = '\0'; 
      fprintf(stdout, "Got: %s", buffer); 
      string from_client(buffer); 
      string to_client = dict[from_client]; 

      char buff[1024]; 

      strncpy(buff, to_client.c_str(), strlen(buff)); 
      buff[strlen(buff) - 1] = '\0'; 

      if ((write(client_fd, buff, strlen(buff))) == -1) 
      { 
       fprintf(stderr, "write error\n"); 
       close(client_fd); 
       break; 
      } 

      fprintf(stdout, "I wrote: %s", buff); 

     } 
     close(client_fd); 
} 

void loadDictionary(map <string, string> &dict) 
{ 
    dict.clear(); 
    ifstream file("dict.txt"); 
    string s1, s2; 

    if(file.is_open()) 
    { 
     while(file.good()) 
     { 
      getline(file, s1); 
      getline(file, s2); 
      dict.insert(pair<string, string>(s1, s2)); 
     } 
    } 

    file.close(); 
} 

int main(int argc, char **argv) 
{ 
    int server_soc_fd, port, buffsize = 1024; 
    char buffer[buffsize]; 
    struct sockaddr_in addr; 
    socklen_t addrlen = sizeof(addr); 
    loadDictionary(dict); 

    if (argc < 2) 
    { 
     fprintf(stderr, "Use : ./server {port number}\n"); 
     exit(1); 
    } 

    port = atoi(argv[1]); 
    addr.sin_family = AF_INET; 
    addr.sin_port = htons(port); 
    addr.sin_addr.s_addr = INADDR_ANY; 
    server_soc_fd = socket(AF_INET, SOCK_STREAM, 0); 

    if(server_soc_fd < 0) 
    { 
     perror("socket"); 
     exit(1); 
    } 

    if(bind(server_soc_fd,(struct sockaddr *)&addr, addrlen) < 0) 
    { 
     perror("bind"); 
     exit(1); 
    } 

    if(listen(server_soc_fd, 10) < 0) 
    { 
     perror("listen"); 
     exit(1); 
    } 

    fprintf(stdout, "\nWorking...\n\n"); 

    while(true) 
    { 
     int client_soc_fd = accept(server_soc_fd, NULL, NULL); 
     pthread_t thread; 
     pthread_create(&thread, NULL, clients_service, (void*)client_soc_fd); 
    } 

    return 0; 
} 
+1

這是C++你寫什麼,而不是C. – glglgl

+0

任何想法爲什麼不想工作...? – yak

回答

1

此:

char buff[1024]; 

strncpy(buff, to_client.c_str(), strlen(buff)); 
buff[strlen(buff) - 1] = '\0'; 

不會填滿buff

char *strncpy(char *dest, const char *src, size_t n); 

副本n字節從srcdest

所以您做的更好:

const char * cstr = to_client.c_str(); 
size_t len = strlen(cstr); 
strncpy(buff, cstr, max(len, sizeof(buff)-1)); 
buff[len] = 0; 

甚至做得更好:

const char * cstr = to_client.c_str(); 
size_t len = strlen(cstr); 
if (!len) 
    continue; 

if ((write(client_fd, cstr, len) == -1) 
{ 
    ... 

而且你不應該依賴write()一次寫的所有數據。

所以,你可能會延長它,就像這樣:

... 
const char * cstr = to_client.c_str(); 
size_t len = strlen(cstr); 

size_t lenWrittenTotal = 0; 
while (lenWrittenTotal < len); 
{ 
    ssize_t lenWritten = write(client_fd, cstr + lenWrittenTotal , len - lenWrittenTotal); 

    if (lenWritten < 0) 
    { 
    perror("write"); 
    break; 
    } 
    else if (lenWritten > 0) 
    { 
    lenWrittenTotal += lenWritten; 
    } 
    else 
    { 
    ... 
    break; 
    } 
}; 
... 
+0

更改爲你建議,仍然不工作 – yak

+0

,你'''在'strncpy'行:)但無論如何,與此修復它不想工作:( – yak

+0

添加它.Thy。@yak – alk