c - 使用套接字的二进制文件的问题

标签 c sockets binaryfiles binary-data

这不是全部代码。

这对于文本文件等普通文件工作正常,但对于 tar.gz 和二进制文件传输不起作用,请帮助我。

以及如何使用套接字发送内存块。

服务器.c

void main()
{
int sockfd, new_fd;  // listen on sock_fd, new connection on new_fd
struct sockaddr_in my_addr; // my address information
struct sockaddr_in their_addr; // connector's address information
socklen_t sin_size;
struct sigaction sa;
int yes=1;
char buf[16384];
char remotefile[MAXDATASIZE];
if ((sockfd = socket(AF_INET, SOCK_STREAM, 0)) == -1)
{
    perror("socket");
    exit(1);
}

if (setsockopt(sockfd, SOL_SOCKET, SO_REUSEADDR, &yes, sizeof(int)) == -1) 
{
    perror("setsockopt");
    exit(1);
}

my_addr.sin_family = AF_INET;        // host byte order
my_addr.sin_port = htons(MYPORT);    // short, network byte order
my_addr.sin_addr.s_addr = INADDR_ANY; // automatically fill with my IP
memset(my_addr.sin_zero, '\0', sizeof my_addr.sin_zero);

printf("call binding\n");
if (bind(sockfd, (struct sockaddr *)&my_addr, sizeof my_addr) == -1) 
{
    perror("bind");
    exit(1);
}

if (listen(sockfd, BACKLOG) == -1) 
{
    perror("listen");
    exit(1);
}

sa.sa_handler = sigchld_handler; // reap all dead processes
sigemptyset(&sa.sa_mask);
sa.sa_flags = SA_RESTART;
if (sigaction(SIGCHLD, &sa, NULL) == -1) 
{
    perror("sigaction");
    exit(1);
}

while(1)
{  // main accept() loop
    sin_size = sizeof their_addr;
    if ((new_fd = accept(sockfd, (struct sockaddr *)&their_addr, &sin_size)) == -1) 
    {
        perror("accept");
        exit(1);
        continue;
    }
    printf("server: got connection from %s\n",inet_ntoa(their_addr.sin_addr));
    if (!fork()) 
    { // this is the child process
if ((byt=recv(new_fd, remotefile, MAXDATASIZE-1, 0)) == -1) 
            {
                perror("server recv");
                exit(1);
            }
        int serverfile_fd;
        size_t result;
        printf("\nremotefile in val1 is %s\n",remotefile);

        if((serverfile_fd = open(remotefile,O_RDONLY)) < 0)
        {
            printf("error at remotefile\n");
            exit(1);
        }

        else
         {  
            read(serverfile_fd, &buf[0], sizeof(buf));
         }
        //printf("file is\n%s", buf);
        /* 3. sending  buf in val 0*/
        if (send(new_fd, buf, 16384, 0) == -1)
            perror("send");
        close(new_fd);
        exit(0);
    }

客户端.c

int remote_to_local(const  char *remotehost,const  char *remotefile,const  char *localfile)
{

int sockfd, numbytes,i = 0,j = 0;  
char buf[16384];
struct hostent *he;
struct sockaddr_in s_addr; // connector's address information 
printf("\n");
printf("Remotehost is %s\n", remotehost);
if ((he=gethostbyname(remotehost)) == NULL) 
{  // get the host info 
    perror("gethostbyname");
    exit(1);
}

if ((sockfd = socket(AF_INET, SOCK_STREAM, 0)) == -1) 
{
    perror("socket");
    exit(1);
}

s_addr.sin_family = AF_INET;    // host byte order 
s_addr.sin_port = htons(PORT);  // short, network byte order 
s_addr.sin_addr = *((struct in_addr *)he->h_addr);
//inet_aton(he->h_addr, &s_addr.sin_addr);
memset(s_addr.sin_zero, '\0', sizeof s_addr.sin_zero);

if (connect(sockfd, (struct sockaddr *)&s_addr, sizeof s_addr) == -1) 
{
    perror("connect");
    exit(1);
}

//send(sockfd, remotefile, MAXDATASIZE-1, 0);
val[0] = 1;
printf("Val 0 is %d\n", val[0]);
printf("Val 1 is %d\n", val[1]);
        /*1 sending val in r to l*/
if (send(sockfd, val, MAXDATASIZE-1, 0) == -1)
            perror("send");

printf("remotefile is %s\n",remotefile);

/* 2 sending remotefile in r to l*/
if (send(sockfd, remotefile, MAXDATASIZE-1, 0) == -1)
            perror("send");
/* 3. recieve buf in r to l */  
if ((numbytes=recv(sockfd, buf, 16384, 0)) == -1) 
{
    perror("recv");
    exit(1);
}

buf[numbytes] = '\0';

//printf("Received: \n%s",buf);


int clientfile_fd;
printf("Local file is %s\n",localfile);
if((clientfile_fd = open(localfile,O_CREAT|O_WRONLY,0777)) < 0)
    {
       printf("error at remotefile\n");
        exit(1);
    }
   else
   {    
        //read(clientfile_fd, &buf[0], sizeof(buf));
         int  result = strlen(buf); 
         //printf("Result size is %d\n",result);
         open(localfile,O_TRUNC);
         write(clientfile_fd, &buf[0], result);
   }

close(sockfd);


return 0;
  }

最佳答案

检查所有代码并修复/更改所有位置:

  • 没有正确处理系统调用返回的结果,例如 接收()。如果返回正值,则该值是唯一安全的 找出有多少数据已读入缓冲区的方法。
  • 去掉所有的 strlen()、printf("%s...) 等 无用,(二进制数据可能包含空值,因此该操作将 提前完成),或者危险,(二进制数据根本不包含空值 所以调用是 UB)。

关于c - 使用套接字的二进制文件的问题,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/31569425/

相关文章:

java - 如何取消阻塞在 ServerSocket.accept() 上阻塞的线程?

c - 从c中的二进制文件中读取double

c - c-sel函数中的scandir实现

c++ - 自动比较两个系列-相异性测试

检查 malloc 之前和 free C 之后的内存状态

python - OpenMP 和 Cython 缺乏加速和错误结果

java - Python 在接收行的末尾添加一个额外的 CR

java - 通过套接字 java 的 CipherOutputStream

matlab - 如何将 Matlab 工作区数据打包/解包到二进制文件中?

c++ - Boost 二进制文件读取错误 unsupported version