客户端在tcp中与服务器连接后无法读取

时间:2015-04-13 06:13:08

标签: 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 > 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是与客户端通信的新套接字。读写功能在服务器端完美运行。在客户端编写功能工作。但从服务器读取不适用于客户端程序。我的代码上的蚂蚁错误?

3 个答案:

答案 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;
}