我为tcp程序编写了读写函数。我在服务器端输出但我无法在客户端读取。我的代码
读取功能:
int read_data (int sd , char **data_buf)
{
int in_length,length,size,bytesread;
char *temp_buf;
size = read(sd,&in_length,sizeof(in_length));/*send entire length of data*/
if( 0 > size )
{
printf("Error on reading from socket\n");
exit(1);
}
length = ntohl(in_length);
printf("Total length coming : %d\n",length);
*data_buf =(char *)malloc((length+1)*sizeof(char));
temp_buf =(char *)malloc((length+1)*sizeof(char));
while(length> 0)
{
bytesread = read(sd,temp_buf,4);
strcat(*data_buf,temp_buf);
temp_buf = temp_buf + bytesread;
length = length - bytesread;
}
return 1;
}
我的写作如下:
int write_data (int sd , char *buffer)
{
int length,len_buff,bytesread,size;
len_buff = strlen(buffer);/*total length of string*/
printf("string == %s\n",buffer);
length = htonl(len_buff);/*convert to host to n/w*/
printf("Total length send =%d\n",len_buff);
size = write(sd,&length,sizeof(length));/*write total size to server */
if( 0 > size)
{
printf("error\n");
exit(0);
}
while(length > 0)
{
bytesread = write(sd,buffer,4);/*write 4 bytes to server*/
buffer = buffer + bytesread;
length = length - bytesread;
}
return 1;
}
客户端程序:
///.............code for socket and connections.................//
ret = write_data(sd,user_string);/*write entire datas to server*/
value_from_server = read_data(sd,&data_buf);
服务器端程序:
value_from_client = read_data(connfd,&data_buf);
printf("the value from client : %s\n",data_buf);
index = string_function(data_buf,&store_buf);
printf("after string process : %s\n",store_buf);
write_data(connfd,store_buf);
printf("i am waiting for next string\n");
connfd是与客户端通信的新套接字。读写功能在服务器端完美运行。在客户端编写功能工作。但从服务器读取不适用于客户端程序。我的代码上的蚂蚁错误?
答案 0 :(得分:1)
bytesread = read(sd,temp_buf,4);
为什么总是在循环内读取4个字节?您应该读取要读取的剩余字节数。套接字是阻塞的,因此如果服务器完成发送将被卡住但客户端仍尝试读取4个字节以在最后一次迭代中到达。
在循环中使用print语句以了解每次迭代中读取的字节数,并查看客户端是否被read
答案 1 :(得分:0)
您的代码有几个逻辑错误。
size = read(sd,&in_length,sizeof(in_length));/*send entire length of data*/
if( 0 > size )
{
printf("Error on reading from socket\n");
exit(1);
}
length = ntohl(in_length);
在这里,您假设您读取了四个字节,而不是更少,或者流的结尾。您必须检查流的结束(零返回值),并且必须循环,直到获得四个字节。
while(length> 0)
{
bytesread = read(sd,temp_buf,4);
strcat(*data_buf,temp_buf);
temp_buf = temp_buf + bytesread;
length = length - bytesread;
}
这里再次忽略了流结束或错误的可能性。它应该是:
while ((bytesread = read(sd,temp_buf, length)) > 0)
{
temp_buf += bytes_read;
length -= bytesread;
}
if (bytesread < 0)
{
perror("read 2");
}
else if (length > 0)
{
// end of stream before all expected bytes were received ...
}
else
{
// The OK case
}
您的发送代码不是最理想的:
while(length > 0)
{
bytesread = write(sd,buffer,4);/*write 4 bytes to server*/
buffer = buffer + bytesread;
length = length - bytesread;
}
分块写入4字节写入没有意义。它应该是:
while (length > 0)
{
bytesread = write(sd, buffer, length);
buffer = buffer + bytesread;
length = length - bytesread;
}
当然应该调用错误的bytesread
变量byteswritten.
实际上你可以依赖这个循环只执行一次。同样应该进行byteswritten == -1
测试以检查错误。
答案 2 :(得分:-1)
您的函数中存在逻辑错误。
读取循环在每次迭代时正好读取4个字节。如果正在读取的数据长度不是甚至是4 的多个,则read()
将在最后一次迭代时阻塞,等待未到达的数据。读取循环也假设read()
返回一个以null结尾的缓冲区,但事实并非如此,因此strcat()
将尝试从周围的内存中复制数据,并将使用段错误复制垃圾或崩溃。此外,读取函数不是空终止它返回给调用者的数据缓冲区,但是调用者假定它是以空值终止的。
写循环在每次迭代时写入4个字节。如果数据的长度不是甚至是4 的倍数,write()
将尝试在最后一次迭代时从周围的内存中写入数据,并且会发送垃圾或崩溃并发生段错误。
你也没有在任何一个功能中做足够的错误处理。
尝试更像这样的东西:
void read_raw_bytes (int sd, void *data, int length)
{
int bytes_read;
char *data_ptr;
data_ptr = (char*) data;
while( length > 0 )
{
bytes_read = read(sd, data_ptr, length);
if( bytes_read < 0 )
{
printf("Error on reading from socket\n");
exit(1);
}
if( bytes_read == 0 )
{
printf("Disconnected while reading from socket\n");
exit(1);
}
data_ptr += bytes_read;
length -= bytes_read;
}
}
void write_raw_bytes (int sd, void *data, int length)
{
int bytes_sent;
char *data_ptr;
data_ptr = (char*) data;
while( length > 0 )
{
bytes_sent = write(sd, data_ptr, length);
if( bytes_sent < 0 )
{
printf("Error on writing to socket\n");
exit(0);
}
data_ptr += bytes_sent;
length -= bytes_sent;
}
}
int read_data (int sd, char **data_buf)
{
int length;
read_raw_bytes (sd, &length, sizeof(length)); /*send entire length of data*/
length = ntohl(length);
printf("Total length coming : %d\n", length);
*data_buf = (char *) malloc((length+1)*sizeof(char));
if (*data_buf == NULL)
{
printf("Error on allocating memory\n");
exit(1);
}
read_raw_bytes (sd, *data_buf, length);
(*data_buf)[length] = 0;
return 1;
}
int write_data (int sd, char *buffer)
{
int length, len_buff;
len_buff = strlen(buffer); /*total length of string*/
printf("string == %s\n", buffer);
printf("Total length send =%d\n", len_buff);
length = htonl(len_buff); /*convert to host to n/w*/
write_raw_bytes (sd, &length, sizeof(length)); /*write total size to server */
write_raw_bytes (sd, buffer, len_buff);
return 1;
}