我正在开发一个基于TCP的聊天程序,它允许我通过WAN在两台机器之间进行通信。我对c++还是个新手(来自Java),对TCP也是个新手,所以不要对我太苛刻!我查阅了大量的教程,仍然发现只有Echo程序,没有任何程序可以长时间保持连接以允许聊天之类的功能。我当前的代码是这样的:
#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 hostn");
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()] = ' ';
// 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("%sn",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: %sn",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: %sn",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()时,我才会遇到错误,特别是分段错误。这只发生在第二条消息上,第一条消息被正确地发送和接收。
如果有人能帮助我,我将不胜感激。谢谢!在ClientManager::message中,您忘记在方法末尾删除缓冲区。或者,您应该像这样在本地堆栈上声明缓冲区:
char buffer[msg.size() + 1];
这样,缓冲区将在调用结束时自动释放。阅读后面的代码,你最好这样做:
char buffer[256];
我认为读取服务器回复的代码会导致缓冲区溢出,如果你的msg.size() <serverReply。大小,即使您认为您有256个字符(您只是在方法开始时没有分配它们)。请注意这个缓冲区长度声明和以后的处理,因为c++会让你写超出它的结束,破坏相邻的变量并导致段错误。>