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/IP协议从Android接收文本文件到C。我的数据丢失了_C_Sockets_System Calls_Tcp Ip - Fatal编程技术网

如何使用TCP/IP协议从Android接收文本文件到C。我的数据丢失了

如何使用TCP/IP协议从Android接收文本文件到C。我的数据丢失了,c,sockets,system-calls,tcp-ip,C,Sockets,System Calls,Tcp Ip,我已经编写了一个从Android到C的文件接收代码,但问题是我接收到的数据丢失。当接收到的文本文件与原始文本文件进行检查时,字节不匹配。如何根除这一现象?我已经给出了代码以供参考` #include<stdio.h> #include<unistd.h> #include<string.h> #include<stdlib.h> #include<sys/ioctl.h> #include<sys/

我已经编写了一个从Android到C的文件接收代码,但问题是我接收到的数据丢失。当接收到的文本文件与原始文本文件进行检查时,字节不匹配。如何根除这一现象?我已经给出了代码以供参考`

  #include<stdio.h>
  #include<unistd.h>
  #include<string.h>    
  #include<stdlib.h>
  #include<sys/ioctl.h>
  #include<sys/types.h>
  #include<arpa/inet.h>
  #include<sys/socket.h>

  int receive_text(long int new_socket)
  {
      int buffersize = 0, recv_size = 0, size = 0, read_size,     write_size;
      char verify = '1';
      int errno;
      FILE *text;
      char *pBuf;

      //Find the size of the text
      recv(new_socket, (char *)&size, sizeof(int), 0);
      //Send our verification signal
      //send(new_socket, &verify, sizeof(char), 0);
      text = fopen("/home/sosdt009/Desktop/received.txt", "w");

      if (text == NULL)
      {
        puts("Error has occurred. Text file could not be opened \n");
        return -1;
      }

      //Loop while we have not received the entire file yet
      while (recv_size < size)
      { 
         ioctl(new_socket, FIONREAD, &buffersize);
         //We check to see if there is data to be read from the socket 
         if (buffersize > 0)
         {
            pBuf = malloc(buffersize);
            if (!pBuf)
            {
              fprintf(stderr, "Memory Error. Cannot allocate!\n");
              exit(-1);
            }
            //memset(pBuf,0,buffersize);
            read_size = recv(new_socket, pBuf, buffersize, 0);
            if (read_size < 0)
            {
               printf("%s", strerror(errno));
            }
            //Write the currently read data into our text file
            write_size = fwrite(pBuf, 1, buffersize, text);
            free(pBuf);
            printf("%d \n", write_size);
            //Increment the total number of bytes read
            recv_size += write_size;        
            printf(" %d \n", recv_size);
        }           
     }
     fclose(text);
     return 1;
 }

 int main(int argc , char *argv[]) {
    int socket_desc , new_socket, c, read_size, buffer = 0;
    struct sockaddr_in server , client;
    char *readin;
    //Create socket
    socket_desc = socket(AF_INET,SOCK_STREAM,0);
    if (socket_desc == -1)
    {
      printf("Could not create socket:");
    }
    //Prepare the sockaddr_in structure
    server.sin_family = AF_INET;
    server.sin_addr.s_addr = INADDR_ANY;
    server.sin_port = htons( 6777 );
    //Bind
    if( bind(socket_desc,(struct sockaddr *)&server , sizeof(server)) < 0)
    {
       puts("bind failed");
       return 1;
    }
    puts("Bind completed");
    //Listen
    listen(socket_desc,3);
    //Accept and incoming connection
    puts("Waiting for incoming connections...");
    c = sizeof(struct sockaddr_in);
    if((new_socket = accept(socket_desc,(struct sockaddr *)&client,(socklen_t *)&c)) )
    {
      puts("Connection accepted");
    }
    fflush(stdout);
    close(socket_desc);
    if (new_socket<0)
    {
        perror("Accept Failed");
        return 1;
    }
    while(1)
    {       
      receive_text(new_socket);
    }
    close(socket_desc);
    return 0;
 }
#包括
#包括
#包括
#包括
#包括
#包括
#包括
#包括
int接收_文本(长int新_套接字)
{
int buffersize=0,recv_size=0,size=0,read_size,write_size;
char verify='1';
int errno;
文件*文本;
char*pBuf;
//查找文本的大小
recv(新的_插座,字符*)和大小,sizeof(int),0;
//发送我们的验证信号
//发送(新的_套接字,&verify,sizeof(char),0);
text=fopen(“/home/sosdt009/Desktop/received.txt”,“w”);
if(text==NULL)
{
puts(“发生错误。无法打开文本文件\n”);
返回-1;
}
//循环,而我们还没有收到整个文件
while(recv_size0)
{
pBuf=malloc(缓冲区大小);
if(!pBuf)
{
fprintf(stderr,“内存错误。无法分配!\n”);
出口(-1);
}
//memset(pBuf,0,buffersize);
read_size=recv(新的_套接字,pBuf,buffersize,0);
如果(读取大小<0)
{
printf(“%s”,strerror(errno));
}
//将当前读取的数据写入文本文件
write_size=fwrite(pBuf,1,buffersize,text);
免费(pBuf);
printf(“%d\n”,写入大小);
//增加读取的总字节数
记录大小+=写入大小;
printf(“%d\n”,记录大小);
}           
}
fclose(文本);
返回1;
}
int main(int argc,char*argv[]){
intsocket\u desc,new\u socket,c,read\u size,buffer=0;
服务器、客户端中的结构sockaddr_;
char*readin;
//创建套接字
socket\u desc=socket(AF\u INET,SOCK\u STREAM,0);
如果(套接字描述==-1)
{
printf(“无法创建套接字:”);
}
//在结构中准备sockaddr_
server.sinu family=AF\u INET;
server.sin\u addr.s\u addr=INADDR\u ANY;
server.sin_port=htons(6777);
//束缚
if(绑定(socket_desc,(struct sockaddr*)&server,sizeof(server))<0
{
看跌期权(“绑定失败”);
返回1;
}
看跌期权(“绑定完成”);
//听
听(插座描述,3);
//接受和传入连接
puts(“等待传入连接…”);
c=sizeof(结构sockaddr_in);
if((new_socket=accept(socket_desc,(struct sockaddr*)和client,(socklen_t*)和c)))
{
看跌期权(“已接受连接”);
}
fflush(stdout);
关闭(插座描述);
如果(新插座在这里

recv()
告诉您它在当前迭代中收到了多少字节,但不包括
read\u size
字节

这里呢

write_size = fwrite(pBuf, 1, buffersize, text);
您忽略接收的字节数,但总是写入
buffersize

通过将实际接收的数据量写入目标文件来解决此问题:

write_size = fwrite(pBuf, 1, read_size, text);

调用
recv()
接收到的字节数将完全忽略任何错误检查

在传输二进制数据时,您还需要确保不会绊倒

  • 发送方和接收方上整数值的宽度可能不同
  • 发送方和接收方的端点不同
  • 要解决上述第一个可能的问题,请使用定义良好的位宽度数据类型。此处
    int32\u t
    而不是
    int
    或可能是未签名的学究:
    unint32\u t

    对于第二个可能的陷阱,以网络字节顺序传输数据。为了实现这一点,不要发送普通的
    int
    (或
    uint32\u t
    ),而是通过调用
    htonl()
    ,将其转换为网络字节顺序(在发送之前)。在接收端,然后使用
    ntohl()
    将其转换回主机字节顺序


    发送方在传输过程中关闭套接字的情况将被忽略,但应通过测试
    recv()
    的结果与
    0
    进行比较来处理,这表明发送方关闭了套接字


    在调用
    accept()
    时将
    int c
    强制转换为
    socklen\t
    ,也可能会引发未定义的行为

    来解决这个问题,而不是

    int c;
    
    定义

    socklen_t c;
    

    另外,代码关闭
    socket\u desc
    两次,并且根本不关闭
    new\u socket


    Also3正在做什么

    测试数据是否可用是有意义的,因为套接字的缓冲区是由内核异步填充到程序的,所以调用
    ioctl()
    返回的值可能在一瞬间就过时了


    只需删除对
    ioctl()
    的调用,并定义一个固定大小的缓冲区来读取。
    recv()
    将阻止,直到数据可用。

    我已根据上面的注释修改了代码,但仍然丢失了数据。您可能希望在收到时记录
    size
    的值,并验证其正确性。
    socklen_t c;
    
    ioctl(new_socket, FIONREAD, &buffersize);