我假设对于只有1个字节(char)的消息,我将直接使用read()和write()。
对于那些尺寸大于>的消息1个字节,我使用两个子函数来读取和写入套接字。
例如,我让服务器构造一个名为strcities(城市列表)的字符串并将其打印出来 - >没什么奇怪的然后将此字符串的字节数发送给客户端,然后发送实际的字符串。
客户端将首先读取字节数,然后读取实际的城市列表。
出于某种原因,我的代码有时会起作用,有时甚至不起作用。如果它有效,它还打印出一些额外的字符,我不知道它们来自哪里。如果它没有,它会挂起并永远在客户端等待,而服务器返回到循环的顶部并等待来自客户端的下一个命令。您能否请看下面的代码,让我知道我哪里做错了?
Attempt_read
string attempt_read(int rbytes) { // rbytes = number of bytes of message to be read
int count1, bytes_read;
char buffer[rbytes+1];
bool notdone = true;
count1 = read(sd, buffer, rbytes);
while (notdone) {
if (count1 == -1){
perror("Error on write call");
exit(1);
}
else if (count1 < rbytes) {
rbytes = rbytes - count1; // update remaining bytes to be read
count1 = read(sd, buffer, rbytes);
}
else {notdone = false;}
} // end while
string returnme;
returnme = string(buffer);
return returnme;
}
Attempt_write
void attempt_write(string input1, int wbytes) { // wbytes = number of bytes of message
int count1;
bool notdone = true;
count1 = write(sd, input1.c_str(), wbytes);
while (notdone) {
if (count1 == -1){
perror("Error on write call");
exit(1);
}
else if (count1 < wbytes) {
wbytes = wbytes - count1;
count1 = write(sd, input1.c_str(), wbytes);
}
else {notdone = false;}
} // end while
return;
}
答案 0 :(得分:1)
1)字符串类有一个方法size(),它将返回字符串的长度,因此实际上你不需要第二个attempt_write参数。
2)您可以在消息之前传输消息长度,或者如果您只发送ASCII字符串,则可以在之后传输终止0。由于您的连接可以随时终止,因此最好在发送字符串之前发送确切的长度,以便您的客户知道会发生什么。
3)你使用什么编译器,允许char缓冲区[rbytes + 1]; ?标准的c ++需要char buffer = new char [rbytes + 1];并相应删除以避免内存泄漏。
4)在您的代码中,第二个读取函数调用使用相同的缓冲区而不调整长度,因此您实际上会覆盖已接收的数据,并且只有在第一个函数调用中接收到所有数据时该函数才会起作用。写功能也是如此
我会建议这样的事情:
void data_read(unsigned char * buffer, int size) {
int readed, total = 0;
do {
readed = read(sd, buffer + total, size - total);
if (-1 == writted) {
perror("Error on read call");
exit(1);
}
total += readed;
} while (total < size);
}
string attempt_read() {
int size = 0;
data_read((unsigned char *) &size, sizeof(int));
string output(size, (char) 0x0);
data_read((unsigned char *) output.c_str(), size);
return output;
}
void data_write(unsigned char * buffer, int size) {
int writted, total = 0;
do {
writted = write(sd, buffer + total, size - total);
if (-1 == writted) {
perror("Error on write call");
exit(1);
}
total += writted;
} while (total < size);
}
void attempt_write(string input) {
int size = input.size();
data_write((unsigned char *) &size, sizeof(int));
data_write((unsigned char *) input.c_str(), size);
}