This回答显示了在c / c ++中通过套接字发送和接收整数的方法。基于我写的以下两个函数,sendKInt和receiveKInt发送和接收K个整数。但它不能正常工作。也许我的指针算术是错误的,但我找不到错误。请帮忙,我是c ++的新手。另请参阅sendTill和receiveTill函数。
bool sendKInt(int fd, int num[], int k){ // returns true on success
int32_t conv[k];
char *data;
for (int i=0; i<k; i++){
conv[i] = htonl(num[i]);
char *data = (char*)conv;
}
return sendTill(sizeof(int32_t)*k, fd, data);
}
bool receiveKInt(int fd, int *num, int k){ // returns true on success
int32_t ret[k];
int toReturn = receiveTill(sizeof(int32_t)*k,fd,(char*)ret);
for (int i=0; i<k; i++){
num[i] = ntohl(ret[i]);
}
return toReturn;
}
bool sendTill(int size, int fd, char* dataU){ // dataU - dataUser pointer is NULL then create your own buffer and send random thing // returns true on successs
char *data;
int left = size;
int rc;
if(dataU == NULL){
data = (char*)malloc(size);
}else{
data = dataU;
}
while (left) {
rc = write(fd, data + size - left, left);
if (rc < 0){
cout <<"-1 in sendTill \n";
return false;
}
left -= rc;
}
return true;
}
bool receiveTill(int size, int fd, char* data){ // just give a char pointer after allocating size // returns true on success
int ret;
int left = size;
while (left) {
ret = read(fd, data + size - left, left);
if (ret < 0){
cout <<"-1 in receiveTill \n";
return false;
}
left -= ret;
}
return true;
}
答案 0 :(得分:4)
此
char *data;
与
不同char *data = (char*)conv;
你有两个data
个,一个在for
循环中被分配,一个在外面不是这样
return sendTill(sizeof(int32_t)*k, fd, data);
结束发送外部未初始化的data
。 Crom只知道会发生什么。
幸运的是,没有必要做
char *data = (char*)conv;
几百次,所以
return sendTill(sizeof(int32_t)*k, fd, (char*)conv);
看起来会起作用。可悲的是,它不会在C ++中。
int32_t conv[k];
是无效的C ++。 k
在编译时是未知的,因此这需要非标准的可变长度数组编译器扩展。一些编译器将允许这种语法,但它有一些缺点(常见的实现很容易超出堆栈,并且对sizeof
的行为非常混乱)并且不会在所有编译器上编译。如果您需要将代码移植到其他平台或将代码提交给将评估代码并使用的代码(例如,Visual Studio),那真的很糟糕。
C ++ 11有std::vector::data
所以你可以
bool sendKInt(int fd, int num[], int k){ // returns true on success
std::vector<int32_t> conv(k);
for (int i=0; i<k; i++){
conv[i] = htonl(num[i]);
}
return sendTill(sizeof(int32_t)*k, fd, (char *)conv.data());
}
答案 1 :(得分:2)
你声明了两个data
个变量,第二个隐藏了第一个变量。
bool sendKInt(int fd, int num[], int k){ // returns true on success
int32_t conv[k];
// First "data", points to undefined value
char *data;
for (int i=0; i<k; i++){
conv[i] = htonl(num[i]);
// local data, points to conv
// HIDES the first data declared above
char *data = (char*)conv;
}
// uses the only "data" in scope, which points to undefined location
return sendTill(sizeof(int32_t)*k, fd, data);
}
答案 2 :(得分:2)
为什么它不起作用
目前尚不清楚您是否打算sendKInt()
:
sendTill()
建议,通过sizeof(int32_t)*k
发送所有数据在sendKInt()
循环中,你有两个非常大的错误:
char *data
。此变量使用相同的名称隐藏外部变量,并在退出循环后立即丢失其值。 sendTill()
。这是未定义的行为保证! 如何解决
我假设C使用malloc()
。
bool sendKInt(int fd, int num[], int k){ // returns true on success
int32_t *data = calloc (sizeof(int32_t), k); // allocate for everything
if (data==NULL) // allocation failure
return 0;
for (int i=0; i<k; i++){ // convert everything
data[i] = htonl(num[i]);
}
bool rc = sendTill(sizeof(int32_t)*k, fd, (char*)data);
free(data); // malloc=> free (or you'll leak memory)
return rc; // now that memory is freed, return the result
}
请注意,您必须根据此新逻辑查看其余代码。不要忘记释放在函数中分配的内存,以避免内存泄漏。
答案 3 :(得分:0)
一个很好的代码:
bool sendKInt(int fd, int num[], int k){ // returns true on success
std::vector<int32_t> conv(k);
for (int i=0; i<k; i++){
conv[i] = htonl(num[i]);
}
return sendTill(sizeof(int32_t)*k, fd, (char *)conv.data());
}
bool receiveKInt(int fd, int *num, int k){ // returns true on success
int32_t *ret = (int32_t*)calloc (sizeof(int32_t), k);
bool toReturn = receiveTill(sizeof(int32_t)*k,fd,(char*)ret);
for (int i=0; i<k; i++){
num[i] = ntohl(ret[i]);
}
free(ret);
return toReturn;
}
bool sendTill(int size, int fd, char* dataU){ // dataU - dataUser pointer is NULL then create your own buffer and send random thing // returns true on successs
char *data;
int left = size;
int rc;
if(dataU == NULL){
data = (char*)malloc(size);
}else{
data = dataU;
}
while (left) {
rc = write(fd, data + size - left, left);
if (rc < 0){
cout <<"-1 in sendTill \n";
return false;
}
left -= rc;
}
return true;
}
bool receiveTill(int size, int fd, char* data){ // just give a char pointer after allocating size // returns true on success
int ret;
int left = size;
while (left) {
ret = read(fd, data + size - left, left);
if (ret < 0){
cout <<"-1 in receiveTill \n";
return false;
}
left -= ret;
}
return true;
}