客户可以';在tcp中与服务器连接后无法读取
我为一个tcp程序编写了读写函数。我在服务器端输出,但在客户端无法读取。我的代码 读取功能:客户可以';在tcp中与服务器连接后无法读取,c,sockets,tcp,C,Sockets,Tcp,我为一个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 &
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");
服务器端程序:
///.............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是用于与客户端通信的新套接字。读写功能在服务器端可以完美地工作。在客户端编写函数。但从服务器读取数据在客户端程序中不起作用。我的密码有错吗
bytesread = read(sd,temp_buf,4);
为什么总是在循环中读取4个字节?您应该正在读取要读取的剩余字节数。套接字正在阻塞,因此,如果服务器完成发送,但客户端仍尝试读取4个字节以在最后一次迭代中到达,则套接字将被卡住
在循环中包含print语句,以了解每次迭代中读取的字节数,并查看客户端是否被
read
阻塞。您的函数中有逻辑错误
读取循环在每次迭代中正好读取4个字节。如果正在读取的数据长度不是4的偶数倍,read()
将在最后一次迭代中阻塞,等待未到达的数据。读取循环还假设read()
返回以null结尾的缓冲区,但事实并非如此,因此strcat()
将尝试从周围内存复制数据,并复制垃圾或因segfault而崩溃。另外,reading函数不是null,它终止返回给调用方的数据缓冲区,但调用方认为它是null终止的
写入循环在每次迭代中正好写入4个字节。如果数据长度不是4的偶数倍,write()
将尝试在上一次迭代中从周围内存写入数据,并发送垃圾或因segfault而崩溃
您在这两个函数中也没有进行足够的错误处理
请尝试类似以下内容:
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;
}
void read\u raw\u字节(int-sd,void*数据,int-length)
{
读取整数字节;
字符*数据ptr;
数据_ptr=(字符*)数据;
而(长度>0)
{
字节读取=读取(sd、数据ptr、长度);
如果(字节数_读取<0)
{
printf(“从套接字读取时出错\n”);
出口(1);
}
如果(字节数_读取==0)
{
printf(“从套接字读取时断开连接\n”);
出口(1);
}
数据_ptr+=字节_读取;
长度-=读取的字节数;
}
}
void write_raw_字节(int-sd,void*数据,int-length)
{
已发送的整数字节;
字符*数据ptr;
数据_ptr=(字符*)数据;
而(长度>0)
{
发送的字节数=写入(sd、数据ptr、长度);
如果(发送的字节数<0)
{
printf(“写入套接字时出错\n”);
出口(0);
}
数据_ptr+=发送的字节数;
长度-=发送的字节数;
}
}
整数读取数据(整数sd,字符**数据)
{
整数长度;
读取原始字节(sd,&length,sizeof(length));/*发送整个长度的数据*/
长度=ntohl(长度);
printf(“总长度:%d\n”,长度);
*data_buf=(char*)malloc((长度+1)*sizeof(char));
如果(*data_buf==NULL)
{
printf(“分配内存时出错\n”);
出口(1);
}
读取原始字节(sd,*数据长度);
(*data_buf)[长度]=0;
返回1;
}
int write_数据(int sd,char*缓冲区)
{
整数长度,len_buff;
len_buff=strlen(缓冲区);/*字符串的总长度*/
printf(“字符串==%s\n”,缓冲区);
printf(“发送的总长度=%d\n”,len\u buff);
长度=htonl(len_buff);/*将主机转换为n/w*/
写入原始字节(sd,&length,sizeof(length));/*将总大小写入服务器*/
写入原始字节(sd、缓冲区、len\u buff);
返回1;
}
您的代码有几个逻辑错误
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, length);
buffer = buffer + bytesread;
length = length - bytesread;
}
将数据块分为4字节写入没有意义。应该是:
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, length);
buffer = buffer + bytesread;
length = length - bytesread;
}
当然,命名错误的
bytesread
变量应该被称为bytesread。
事实上,这个循环只能执行一次。同样,接下来应该进行bytesWrited==-1
测试,以检查错误。可能是客户端正在发送足够的字节,以便read
返回并退出循环?read()
不会“阻止上一次迭代,等待未到达的数据”。一旦至少传输了一个字节,或流结束或出现错误,它就会解除阻塞。它不会尝试填充缓冲区。