在Ubuntu上使用C++的TCP上的聊天程序的问题12.10

问题描述:

我正在通过TCP开发一个聊天程序,以允许我通过WAN在两台机器之间进行通信。我对C++(来自Java)非常陌生,对TCP很新,所以不要太过于苛刻! (:我浏览了大量的教程,并继续找到只有Echo程序,没有任何东西可以让连接打开很长时间以允许像功能聊天。我现在的代码如下所示:在Ubuntu上使用C++的TCP上的聊天程序的问题12.10

#include "ClientManager.h" 

ClientManager::ClientManager() { 

} 

void ClientManager::connectCom(char* ipAdd) { 



portno = atoi(PORT); 
sockfd = socket(AF_INET, SOCK_STREAM, 0); 
if (sockfd < 0) 
    error("ERROR opening socket"); 
server = gethostbyname(ipAdd); 
if (server == NULL) { 
    fprintf(stderr,"ERROR, no such host\n"); 
    exit(0); 
} 
bzero((char *) &serv_addr, sizeof(serv_addr)); 
serv_addr.sin_family = AF_INET; 
bcopy((char *)server->h_addr, 
    (char *)&serv_addr.sin_addr.s_addr, 
    server->h_length); 
serv_addr.sin_port = htons(portno); 
if (connect(sockfd,(struct sockaddr *) &serv_addr,sizeof(serv_addr)) < 0) 
    error("ERROR connecting"); 
} 

void ClientManager::message(std::string msg) { 
// printf("Please enter the message: "); 

char * buffer = new char[msg.size() + 1]; 
std::copy(msg.begin(), msg.end(), buffer); 
buffer[msg.size()] = '\0'; 
// bzero(buffer,256); 
// fgets(buffer,255,stdin); 
n = write(sockfd,buffer,strlen(buffer)); 
if (n < 0) 
    error("ERROR writing to socket"); 
bzero(buffer,256); 
n = read(sockfd,buffer,255); 
if (n < 0) 
    error("ERROR reading from socket"); 
printf("%s\n",buffer); 
bzero(buffer,256); 
} 

void ClientManager::closeCom() { 
close(sockfd); 
} 

void ClientManager::error(const char *msg) 
{ 
perror(msg); 
exit(0); 
} 

和我的服务器管理器看起来像这样:

#include "ServerManager.h" 

ServerManager::ServerManager() { 
    // int sockfd, portno, n; 
//   struct sockaddr_in serv_addr; 
//  struct hostent *server; 

} 

void ServerManager::openCom() { 
char buffer[256]; 
struct sockaddr_in serv_addr, cli_addr; 
int n; 
    socklen_t clilen; 


sockfd = socket(AF_INET, SOCK_STREAM, 0); 
if (sockfd < 0) 
    error("ERROR opening socket"); 
bzero((char *) &serv_addr, sizeof(serv_addr)); 
portno = atoi(PORT); 
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); 
newsockfd = accept(sockfd, 
      (struct sockaddr *) &cli_addr, 
      &clilen); 
if (newsockfd < 0) 
    error("ERROR on accept"); 
bzero(buffer,256); 
// n = read(newsockfd,buffer,255); 
// if (n < 0) error("ERROR reading from socket"); 
// printf("Here is the message: %s\n",buffer); 
// n = write(newsockfd,"I got your message",18); 
// if (n < 0) error("ERROR writing to socket"); 
} 

int ServerManager::readCom() { 
bzero(buffer,256); 
n = read(newsockfd,buffer,255); 
if (n < 0) error("ERROR reading from socket"); 
    printf("Here is the message: %s\n",buffer); 
n = write(newsockfd,"I got your message",18); 
if (n < 0) error("ERROR writing to socket"); 
if (buffer[0] == '0') 
    return 1; 
return 0; 
} 

void ServerManager::closeCom() { 
close(newsockfd); 
close(sockfd); 

} 

void ServerManager::error(const char *msg) { 
perror(msg); 
exit(1); 
} 

这两个类是由谁打电话必要的功能独立的主要功能实现我知道这些代码本身是确定用于发送一个MESSAGE-它一直这样做了一段时间,当客户端调用多条消息()时,我经历了错误,特别是一个分段n故障。这只发生在第二条消息上,第一条消息被正确发送和接收。

如果有人能帮助我,这将不胜感激。谢谢!

+0

段错误发生时栈是什么?您可以在gdb中运行该程序,并在崩溃时使用'where'来获取堆栈。见http://www.cs.rochester.edu/~nelson/courses/csc_173/review/gdb.html。 – Blake 2013-03-12 20:39:00

+0

这是GDB的输出。你是这个意思吗? '#0 0xb7e0f884在__nss_hostname_digits_dots()从/lib/i386-linux-gnu/libc.so.6 #1 0xb7e143fd中的gethostbyname()从/lib/i386-linux-gnu/libc.so.6 # 2客户端中的0x08048e62客户端:: connectCom(char *)() #3 0x08048c82在main(argc = 1,argv = 0xbffff354)client.cpp:20 ' – jmarple 2013-03-12 23:38:48

在ClientManager :: message中,您忘记了在方法结尾删除缓冲区。 另外,您应该声明本地堆栈,因为这对缓冲:

char buffer[msg.size() + 1]; 

因此,缓冲区将自动被调用结束时释放。 而阅读后的代码,您做的更好:

char buffer[256]; 

我觉得代码读取服务器的答复会导致如果你的msg.size()< serverReply.size缓冲区溢出,即使你认为你有256个字符(你只是没有在方法开始时分配它们)。请注意这个缓冲区长度声明和稍后的处理,因为C++会让你写超出它的结尾,破坏相邻变量并导致段错误。