hi there,
like almost everybody else here i've got a problem.
I am working on a simplified IRC for unix, consisting of a server and a client. It's a task for university..
my problem is, my client receives strange signs from the server and when i want to parse them there are lots of more strange signs! I think the problem is that i dont convert strings and chars correctly or something in my assignments is wrong, but what?! Or maybe i got a logical problem with my STDIN_FILENO and select().
now here's the code for you gurus and experts out there, willing to help a poor student that has learned Java and is collecting his first experiences in C++.
here are is a part of the code, please dont be scared if it looks a bit long.
as a short description:
first i create my object client, then i create the sockets and after that i send/receive whatever select() is expecting. i got parts from the code from examples that i found in the www, trying to adapt them to my needs.
If you have any further questions, dont hesitate to ask me.
best regards
cylow22
#include "client.h"
using namespace std;
client::client(string hostname, string port, string nickname) {
this-> hostname = hostname;
this-> port = port;
this->nickname= nickname;
topic="";
startClient(hostname, port);
}
int client::startClient(string hostname, string port) {
const char *host;
const char *service;
service = port.c_str();
host = hostname.c_str();
int error;
struct addrinfo hints;
struct addrinfo *addr0;
memset(&hints, 0, sizeof(hints));
//hints.ai_family = PF_UNSPEC;
hints.ai_family = AF_INET;
hints.ai_socktype = SOCK_STREAM;
hints.ai_protocol = IPPROTO_TCP;
hints.ai_flags = 0;
printf("Looking up host..");
if ((error = getaddrinfo(host, service, &hints, &addr0)) < 0) {
perror(gai_strerror(error));
return 1;
}
printf(" OK \n");
int sockno;
struct addrinfo *addr;
for (addr = addr0; addr; addr = addr->ai_next) {
printf("Creating socket (ai_family=%d, ai_socktype=%d, ai_protocol=%d)...\n",
addr->ai_family,
addr->ai_socktype,
addr->ai_protocol
);
if ((sockno = socket(addr->ai_family, addr->ai_socktype, addr->ai_protocol)) < 0) {
perror("socket");
continue;
}
printf(" OK \n");
printf("Connecting to host...");
if ((connect(sockno, addr->ai_addr, addr->ai_addrlen)) < 0) {
perror("connect");
close(sockno);
continue;
}
break;
}
if (!addr) {
printf("No connection found\n");
return 1;
}
printf(" OK \n");
freeaddrinfo(addr0);
bool first_login = true;
std::string input;
std::string cmd;
fd_set read_set0;
FD_ZERO(&read_set0);
FD_SET(STDIN_FILENO, &read_set0);
FD_SET(sockno, &read_set0);
do {
char buffer[1024];
int res;
ssize_t length;
//int length;
fd_set read_set = read_set0;
if ((res = select(sockno + 1, &read_set, NULL, NULL, NULL)) > 0) {
/*
// auto-login isn't working yet
if (first_login==true) {
string logincmd = "/LOGIN ";
cmd = getCommand(logincmd).c_str();
cout<<"getCommand liefert: "<<cmd<<endl;
strcpy(buffer, cmd.c_str());
first_login = false;
}
else { */
if (FD_ISSET(STDIN_FILENO, &read_set)) {
printf("Read STDIN...\n");
if ((length = read(STDIN_FILENO, buffer, sizeof(buffer))) < 0) {
perror("read");
continue;
}
//input = buffer;
cmd = getCommand(buffer).c_str();
cout<<"cmd: "<<cmd<<endl;
strcpy( buffer, cmd.c_str());
cout<<"buffer: "<<buffer<<endl;
buffer[length]='\0';
//strcpy( buffer, input.c_str());
}
printf("Write socket...\n");
buffer[length]='\0';
if ((length = write(sockno, buffer, length)) < 0) {
perror("write");
continue;
}
//}
if (FD_ISSET(sockno, &read_set)) {
printf("Read socket...\n");
if ((length = read(sockno, buffer, sizeof(buffer))) < 0) {
perror("read");
continue;
cout<<"length: "<<length<<endl;
}
else if (length == 0) {
printf("Server closed connection\n");
break;
}
printf("Write STDOUT...\n");
if ((length = write(STDOUT_FILENO, buffer, length)) < 0) {
perror("write");
continue;
}
buffer[length]='\0';
std::string tmp = buffer;
cout<<handleServerMessage(tmp)<<endl;
//cout<<"inc_buffer: "<<buffer<<endl;
}
}
else if (res < 0 && errno == EINTR) {
continue;
}
else {
perror("select");
return 1;
}
}
while (1);
close(sockno);
return 0;
}
std::string client::getCommand(string message) {
int msg_length = message.find(' ', 0);
std::string command = message.substr(0, msg_length);
int channel_msg_length = message.find('/', 0);
std::string oldname;
std::string oldtopic;
std::string cmd_code;
if ((command == "/JOIN" || command == "/join") && message.size() > 6) {
channel = message.substr(msg_length+1, MAXCHANNELNAME);
cout<<"You are in channel "<<channel<<'.'<<endl<<flush;
cmd_code ="10101";
cmd_code+=channel;
return cmd_code;
}
else if (((command == "/LOGIN") || (command == "/login")) && message.size() > 6) {
cmd_code ="10001";
cout<<nickname<<endl;
cmd_code+=nickname;
cout<<cmd_code<<endl;
return cmd_code;
}
else {
cmd_code ="10011";
cmd_code+=topic;
cout<<cmd_code<<endl;
return cmd_code;
}
}
else if((channel_msg_length==-1)) {
cmd_code="10111";
cmd_code+=message;
return cmd_code;
}
}
std::string client::handleServerMessage(string message) {
std::string header=message.substr(0, 5);
int server_msg_length = message.length();
std::string modified_msg;
if (header == "10111") {
modified_msg = message.substr(5, server_msg_length);
return modified_msg;
}
else if (header == "10101") {
std::string temp = ("You are in channel ");
temp += modified_msg;
temp += '.';
return temp;
}
}