Warning: file_get_contents(/data/phpspider/zhask/data//catemap/3/sockets/2.json): failed to open stream: No such file or directory in /data/phpspider/zhask/libs/function.php on line 167

Warning: Invalid argument supplied for foreach() in /data/phpspider/zhask/libs/tag.function.php on line 1116

Notice: Undefined index: in /data/phpspider/zhask/libs/function.php on line 180

Warning: array_chunk() expects parameter 1 to be array, null given in /data/phpspider/zhask/libs/function.php on line 181
客户可以';在tcp中与服务器连接后无法读取_C_Sockets_Tcp - Fatal编程技术网

客户可以';在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 &

我为一个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");
服务器端程序:

 ///.............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()
不会“阻止上一次迭代,等待未到达的数据”。一旦至少传输了一个字节,或流结束或出现错误,它就会解除阻塞。它不会尝试填充缓冲区。