我写了一个服务器,它从客户端获取消息并用它在字典中的单词(我在我的文件中的字典)中响应它们。例如:
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;
}
答案 0 :(得分: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
字节从src
复制到dest
。
所以你最好这样做:
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;
}
};
...