简体   繁体   中英

Having issues with chat program over TCP using C++ on Ubuntu 12.10

I'm developing a chat program over TCP to allow me to communicate between two machines over WAN. I'm pretty new to C++ (coming from Java) and am very new to TCP, so don't go too hard on me! (: I've looked around on a fair amount of tutorials and continue to find only Echo programs, nothing that can leave a connection open for an extended amount of time to allow a chat like function. My current code looks like this:

#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);
}

and my server manager looks like this:

#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);
}

Both of these classes are implemented by separate main functions who call the functions necessary. I know that the code itself is ok for sending a single message- its been doing that for awhile now. Its just when client calls more than one message() that I experience errors, specifically, a segmentation fault. This only happens on the second message, the first one is sent and received appropriately.

If anyone could help me out, it would be greatly appreciated. Thanks!

In ClientManager::message you forget to delete the buffer at the end of the method. ALternatively, you should declare the buffer on the local stack as this:

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

As such, the buffer will be automatically deallocated by the end of the call. And reading later code, you better do:

char buffer[256];

I think the code for reading the server's reply causes buffer overrun if your msg.size() < serverReply.size, even if you think you have 256 characters (you simply didn't allocated them at method start) . Please take care to this buffer length declaration and later handling, as C++ would let you write beyond it's end, corrupting neighbouring variables and leading to segfaults.

The technical post webpages of this site follow the CC BY-SA 4.0 protocol. If you need to reprint, please indicate the site URL or the original address.Any question please contact:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM