在linux下写的客户端只是用来发送文件 在QT中进行接收
首先需要linux的网络需要ping通 将虚拟机的网络8(用于net模式通信)打开,Windows的资源管理器中的服务项将虚拟机的服务打开 ,回到虚拟机 将防火墙关掉 /etc/init.d/iptables stop 再将网络重新打开/etc/init.d/network restart
linux 的服务器代码
#include <stdio.h>
#include <sys/types.h>
#include <sys/socket.h>
#include <string.h>
#include <unistd.h>
#include <arpa/inet.h>
#include <string.h>
#include <fcntl.h>
#define SIZE 1024
#define PORT 9999
typedef struct transfile
{
char file_name[30];
int file_len;
char file_message[1024];
}File;
//sfd 用于和客户端通信
void handl_client(int sfd)
{
char buf[SIZE] = {0};
int flage = 1;
int count1 = 0;
File file;
memset(&file,0, sizeof(file));
if(flage == 1)
{
flage == 0;
FILE* fd1 = fopen("lala.txt","r");
if(fd1 == NULL)
{
perror("fopen");
fclose(fd1);
return ;
}
fseek(fd1,0,SEEK_END);
file.file_len= ftell(fd1);
fseek(fd1,0,SEEK_SET);
printf("文件字符为 :%d\n",file.file_len);
strcpy(file.file_name,"lala.txt");
while((count1 = fread(file.file_message, sizeof(char), 1024, fd1))>0)
{
printf("%d\n", count1);
if((count1 = write(sfd, &file, sizeof(file))) < 0)
{
perror("write");
fclose(fd1);
return ;
}
else
printf("%d\n",count1);
memset(&file, 0, sizeof(file));
}
}
close (sfd);
}
int main()
{
// 1、创建套接字
int listen_fd = socket(AF_INET, SOCK_STREAM, 0);
if (listen_fd == -1)
{
perror ("创建套接字");
return -1;
}
#if 0
struct sockaddr_in
{
short int sin_family; /* Internet地址族 */
unsigned short int sin_port; /* 端口号 */
struct in_addr sin_addr; /* IP地址 */
unsigned char sin_zero[8]; /* 填0 */
};
struct in_addr
{
unsigned long s_addr;
}
S_addr: 32位的地址
#endif
struct sockaddr_in addr;
memset (&addr, 0, sizeof(addr));
addr.sin_family = AF_INET; // 使用IPv4地址族
addr.sin_port = htons(PORT); // 设置端口,要注意转换成网络字节序
addr.sin_addr.s_addr = htonl(INADDR_ANY); // 设置监听的IP地址,INADDR_ANY代表监听本机任意IP地址
// 2、绑定本地地址与端口(命令套接字)
int ret = bind(listen_fd, (struct sockaddr *)&addr, (socklen_t)sizeof(addr));
if (ret == -1)
{
perror ("绑定套接字");
return -1;
}
// 3、监听套接字、设置最大连接数
ret = listen(listen_fd, 5);
while (1)
{
printf ("等待客户端的连接.....\n");
// 4、等待连接;ru'guo如果函数返回,证明接收到了一个客户端的连接
// 函数的返回值是一个新的套接字,用来和这个连接过来的客户端进行通信
// accept 的第二个参数用于保存连接上来的客户端的地址信息,如果不想要,可以设为NULL
// 第三个参数是地址的长度,因为地址类型不确定,长度也会一并返回,所以第三个参数也需要整型地址
struct sockaddr_in client_addr;
int len = sizeof(client_addr);
int conn_fd = accept(listen_fd, (struct sockaddr *)&client_addr, (socklen_t *)&len);
if (conn_fd == -1)
{
perror ("accept");
return -1;
}
printf ("有一个客户端连接,地址是:%s\n", inet_ntoa(client_addr.sin_addr));
// 客户端连接以后,可以使用read/write像操作文件一样取读写数据
handl_client(conn_fd);
}
close (listen_fd);
return 0;
}
Windows 下QT接收文件的代码
#include "widget.h"
#include "ui_widget.h"
#include "QDebug"
#include "QMessageBox"
#include "QHostAddress"
Widget::Widget(QWidget *parent) :
QWidget(parent),
ui(new Ui::Widget)
{
ui->setupUi(this);
tcpSocket = new QTcpSocket(this);
file = new QFile();
connect(tcpSocket,QTcpSocket::readyRead,
[=]()
{
qint64 readlength = tcpSocket->read((char*)&file_trains,1024);
qDebug()<<readlength;
if(strcmp(file_trains.file_name,filename) != 0)
{
filesize = 0;
strcpy(filename,file_trains.file_name);
file->setFileName(filename);
bool isOk = file->open(QIODevice::WriteOnly);
if(isOk == false)
{
qDebug()<<"writeonly error 40";
}
qint64 len = file->write(file_trains.file_message);
filesize += len;
if(filesize == file_trains.file_len)
{
qDebug()<<filesize;
file->close();
QMessageBox::information(this,"文件接收完成");
}
}
else
{
qint64 len = file->write(file_trains.file_message);
filesize += len;
if(filesize == file_trains.file_len)
{
qDebug()<<filesize;
file->close();
QMessageBox::information(this,"文件接收完成");
}
}
}
);
}
Widget::~Widget()
{
delete ui;
}
void Widget::on_pushButton_clicked()
{
QString ip = ui->lineEdit->text();
qint16 port = ui->lineEdit_2->text().toInt();
tcpSocket->connectToHost(QHostAddress(ip),port);
}