使用C ++在计算机之间发送文件

时间:2012-06-29 04:14:50

标签: c++ file network-programming winsock

我正在尝试编写一个程序,通过Internet(或LAN)使用C ++将基本文本文件从一台计算机发送到另一台计算机。我正在研究Winsock,但我读到的所有内容都让它看起来只是用于服务器和客户端之间的通信。我不确定这是我想要做的,还是我正在考虑另一个问题。

编辑:谢谢你们的回答。我不得不选择最好的一个。

6 个答案:

答案 0 :(得分:1)

客户端 - 服务器架构应该可以用于发送文件。 “服务器”只是首先启动的程序,并等待另一个(客户端)连接到它。过去那里,两者之间没有太大区别。在很多情况下,编写代码最容易,因此它会自动尝试联系服务器,如果找不到,则会将自己设置为服务器。

另请注意,使用(特别是)NAT路由器在互联网上工作可能会使代码变得有点棘手。如果您预先配置防火墙以允许连接,并不是那么难,但是否则您通常最终使用UPnP通过防火墙建立连接。与没有涉及NAT的本地工作相比,这可以轻松地使工作量翻倍。

答案 1 :(得分:1)

简而言之:是的,套接字是可行的方法。

"服务器"和"客户"在套接字意义上是通用术语 - 您的系统在任何给定时间运行各种各样的。例如,您的Web浏览器作为HTTP客户端运行(其中HTTP是通过TCP / IP运行的文本限制的主要同步协议); Windows文件共享和远程桌面是"服务器"其他系统连接到。

套接字意义上的服务器和客户端之间的区别(实际上是在TCP / IP意义上)是"服务器"套接字侦听来自远程系统的传入连接(请参阅绑定()上的MSDN或手册页,listen(),accept())而不是"客户端" socket创建到远程系统的传出连接(connect())。

请注意套接字编程可能有点棘手。你所描述的是一个很好的学习练习,但是如果你想要快速完成某些工作,你可能会看看现有的工具,比如netcat。

答案 2 :(得分:0)

  

它似乎只是用于服务器和客户端之间的通信

那又怎样?使一台计算机(即将接收文件)服务器。在该计算机上创建一个套接字并使其侦听端口上的连接。一旦连接到达,根据一些定义的结构获取数据(见下文)

发件人计算机(客户端,类型)将连接到另一台计算机,它知道IP地址和端口号。 (客户端必须知道这两个连接)。建立连接后,它会将数据作为字节序列发送到服务器。

结构

在这里进行通信的两台计算机必须具有已知且被两者都接受的明确定义的结构。最简单的结构将是:

|Length-Of-Data | Data ......  |
 <-- 4 bytes---> <-- n bytes-->

从前4个字节中读取n。这里的4字节(n)代表数据的长度,可能与您的定义不同。

对于文件名,文件类型等,您可以拥有更多“字段”(取决于功能)。

答案 3 :(得分:0)

如果你想通过互联网发送文件,你必须使用套接字,或者更好的是使用套接字实现的其他高级库。

在TCP套接字术语中,客户端和服务器之间没有太大区别:通信是双向的。唯一的区别在于谁在监听传入连接(绑定,监听,接受)以及谁正在启动连接(打开)。

您提到了Winsock,这意味着您正在使用Windows。看一下Windows API,可能会找到一些处理文件传输的高级库(如FTP或HTTP库)。

可能不符合您的要求,但您也可以使用LAN的共享文件夹和Dropbox为Internet同步的文件夹...然后只使用标准IO。

答案 4 :(得分:0)

一般而言,任何文件传输都需要某种服务器/客户端连接。一台计算机需要启动连接,而另一台计算机需要在另一端侦听连接,然后执行第一台计算机指示的操作。

虽然您当然可以使用套接字推出自己的客户端和服务器软件,但根据您希望在哪些计算机之间传输文件,最有可能利用一些现有的客户端/服务器协议。一些比较流行的可能性包括ssh,http或ftp。我认为所有这些协议都应该存在C / C ++库。

如果没有更多信息,我倾向于使用ssh。安装ssh服务器不应该太难,所以你只需编写客户端软件,我认为有一些相当不错的开源库。

编辑:libssh看起来很不错!

答案 5 :(得分:0)

这是在Linux中如何使用C / C ++复制/传输文件的示例。server侦听端口8080。client传输文件名。 server接收文件名,打开文件并将其内容发送给客户端。我出于说明目的故意使用了奇数或较小的缓冲区大小。

server.c文件:

#include <stdio.h>
#include <stdlib.h>
#include <string.h>
#include <ctype.h>
#include <netinet/in.h>
#include <unistd.h>
#include <fcntl.h>

int main (int argc,char *argv[])
{
    struct sockaddr_in p;
    struct sockaddr_in q;
    int z,s,t,x,n,b = sizeof(q);
    char buf[23];
    int fd;

    s = socket(AF_INET,SOCK_STREAM,0);

    bzero (&p,sizeof(p));
    p.sin_family = AF_INET;
    p.sin_addr.s_addr = INADDR_ANY;
    p.sin_port = htons(8080);

    bind (s,(struct sockaddr*)&p,sizeof(p));
    listen(s,13);

    while (1) {
        t = accept (s,(struct sockaddr*)&q, &b);
        n = read(t,buf,23);
        buf[n] = 0;
        printf("%s sent: ",buf);
        fd = open (buf,O_RDONLY);
        z = lseek(fd,0,SEEK_END);
        lseek(fd,0,SEEK_SET);
        x = 0;
        do {
            n = read (fd,buf,23);
            write (t,buf,n);
            x += n;
        } while (x < z);
        printf("%d/%d\n",x,z);
        close(fd);
        close(t);
    }
}

client.c文件:

#include <stdio.h>
#include <string.h>
#include <netdb.h>
#include <unistd.h>
#include <fcntl.h>

void main (int argc, char *argv[]) 
{
    int ret;
    char buf[5];
    int s,n,fd;
    struct sockaddr_in p;
    struct hostent *h;
    char *str = argv[1];

    fd = open (str,O_CREAT | O_WRONLY,S_IRUSR|S_IWUSR);
    h = gethostbyname("127.0.0.1");

    bzero(&p,sizeof(p));
    p.sin_family = AF_INET;
    p.sin_addr.s_addr = htonl(INADDR_ANY);
    p.sin_addr.s_addr = ((struct in_addr*)(h->h_addr))->s_addr;
    p.sin_port = htons(8080);

    s = socket (AF_INET,SOCK_STREAM,0);
    connect (s,(void*)&p,sizeof(p));
    n = write (s,str,strlen(str));
    int idx = 0;
    do {
        n = read (s,buf,5);
        idx += n;
        printf(".");
        fflush(stdout);
        write (fd,buf,n);
    } while (n > 0);
    close (fd);
    close (s);
}

要编译:

  1. 打开终端
  2. gcc -o服务器server.c
  3. gcc -o客户端client.c

./server的身份运行服务器。然后要复制rngoidiot.txt,请以./client rngoidiot.txt运行客户端,然后将使用TCP / IP复制文件。简单组合;-)