利用QT做为client端,纯C语言做为server端,利用tcp协议,实现client端向server端传递文件

 

Linux服务器端
//头文件
#include <stdio.h>
#include <stdlib.h>
#include <string.h>
#include <unistd.h>
#include <errno.h>
#include <sys/types.h>
#include <sys/socket.h>
#include <arpa/inet.h>

#define MAX_SOCKET 100

#ifdef __cplusplus
extern "C"
{
#endif

//create socket
int create_socket(int port);

//accept client
int accept_client(int st);

//recv message
int recv_msg(int st);


#ifdef __cplusplus
}
#endif
//辅助方法
#include "pub.h"

//create socket
int create_socket(int port)
{
    if (port < 0)
    {
        printf("create_socket() param not correct!\n");
        return -1;
    }
    int st = socket(AF_INET, SOCK_STREAM, 0);
    if (st < 0)
    {
        printf("socket() failed ! error message:%s\n", strerror(errno));
        return -1;
    }
    int on = 1;
    if (setsockopt(st, SOL_SOCKET, SO_REUSEADDR, &on, sizeof(on)) < 0)
    {
        printf("setsockopt() failed ! error message:%s\n", strerror(errno));
        close(st);
        return -1;
    }
    struct sockaddr_in addr;
    memset(&addr, 0, sizeof(addr));
    addr.sin_family = AF_INET;
    addr.sin_port = htons(port);
    addr.sin_addr.s_addr = htonl(INADDR_ANY);
    if (bind(st, (struct sockaddr *) &addr, sizeof(addr)) < 0)
    {
        printf("bind() failed ! error message:%s\n", strerror(errno));
        close(st);
        return -1;
    }
    if (listen(st, MAX_SOCKET) < 0)
    {
        printf("listen() failed ! error message:%s\n", strerror(errno));
        close(st);
        return -1;
    }
    return st;
}

//网络地址转化字符串
void sockaddr_toa(const struct sockaddr_in *addr, char *ipaddr)
{
    if (addr == NULL || ipaddr == NULL)
    {
        printf("sockaddr_toa() param nor correct!\n");
        return;
    }
    unsigned char *p = (unsigned char *) &(addr->sin_addr.s_addr);
    sprintf(ipaddr, "%u:%u:%u:%u", p[0], p[1], p[2], p[3]);
}

//accept client
int accept_client(int st)
{
    if (st < 0)
    {
        printf("accept_client() param not correct!\n");
        return -1;
    }
    struct sockaddr_in addr;
    memset(&addr, 0, sizeof(addr));
    socklen_t len = sizeof(addr);
    int client_st = accept(st, (struct sockaddr *) &addr, &len);
    if (client_st < 0)
    {
        printf("accept() failed ! error message :%s\n", strerror(errno));
        return -1;
    }
    char buf[100] = { 0 };
    sockaddr_toa(&addr, buf);
    printf("accept by %s\n", buf);
    return client_st;
}

//recv message
int recv_msg(int st)
{
    if (st < 0)
    {
        printf("recv_msg() param not correct!\n");
        return -1;
    }
    //
    char buf[1024] = { 0 };
    int rc = recv(st, buf, sizeof(buf), 0);
    if (rc < 0)
    {
        printf("recv() failed ! error message:%s\n",strerror(errno));
        return -1;
    } else if (rc == 0)
    {
        printf("client is closed!\n");
        return -1;
    }
    //open the file
    FILE * pfw = NULL;
    pfw = fopen(buf, "w");
    if (pfw == NULL)
    {
        printf("fopen() failed! error message:%s\n", strerror(errno));
        return -1;
    }
    memset(buf, 0, sizeof(buf));
    strcpy(buf, "OK");
    //给客户端发送"OK"
    if (send(st, buf, strlen(buf), 0) <= 0)
    {
        printf("send() failed! error message:%s\n", strerror(errno));
        return -1;
    }
    while (1)
    {
        memset(buf, 0, sizeof(buf));
        rc = recv(st, buf, sizeof(buf), 0);
        if (rc < 0)
        {
            printf("recv() failed ! error message:%s\n",strerror(errno));
            return -1;
        } else if (rc == 0)
        {
            printf("client is closed!\n");
            break;
        }
        fwrite(buf, sizeof(char), rc, pfw);
    }
    //关闭客户端
    close(st);
    printf("文件接收完毕!\n");
    return 0;
}
//服务器端
#include "pub.h"

int main(int arg,char *args[])
{
    if(arg<2)
    {
        printf("please print one param ! \n");
        return -1;
    }
    int port=atoi(args[1]);
    int listen_st=create_socket(port);
    if(listen_st<0) return -1;
    int client_st=accept_client(listen_st);
    if(client_st<0) return -1;
    recv_msg(client_st);
    close(listen_st);
    return 0;
}
.SUFFIXES:.c .o
CC=gcc
SRCS=mserver.c\
    pub.c
OBJS=$(SRCS:.c=.o)
EXEC=mser

start:$(OBJS)
    $(CC) -o $(EXEC) $(OBJS)
    @echo "--------OK--------"
.c.o:
    $(CC) -Wall -g -o $@ -c $<
clean:
    rm -f $(OBJS)
    rm -f $(EXEC) 

 

QT客户端
#ifndef WIDGET_H
#define WIDGET_H

#include <QWidget>
#include <QTcpSocket>
#include <QLabel>
#include <QPushButton>
#include <QLineEdit>
#include <QTextBrowser>

class Widget : public QWidget
{
    Q_OBJECT

public:
    Widget(QWidget *parent = 0);
    ~Widget();
private:
    QTcpSocket *tcpsock;
    QLabel *label1,*label2,*label3;
    QLineEdit *edit1,*edit2;
    QPushButton *btn1;
    QTextBrowser *text1;
    QString filename;
    void mygetfilename(const char *src,int len,char *dest);
private slots:
    void btn1_click();
    void myrecvdata();
};

#endif // WIDGET_H
#include "widget.h"
#include <QHBoxLayout>
#include <QVBoxLayout>
#include <QFileDialog>
#include <QMessageBox>
#include <QHostAddress>

Widget::Widget(QWidget *parent)
    : QWidget(parent)
{
    tcpsock=new QTcpSocket(this);
    connect(tcpsock,SIGNAL(readyRead()),this,SLOT(myrecvdata()));
    label1=new QLabel(tr("IP地址:"));
    label2=new QLabel(tr("端口号:"));
    label3=new QLabel(tr("上传信息"));
    edit1=new QLineEdit();

    edit2=new QLineEdit();
    btn1=new QPushButton(tr("文件上传"));
    text1=new QTextBrowser();
    connect(btn1,SIGNAL(clicked()),this,SLOT(btn1_click()));
    QHBoxLayout *lay1=new QHBoxLayout();
    lay1->addWidget(label1);
    lay1->addWidget(edit1);

    QHBoxLayout *lay2=new QHBoxLayout();
    lay2->addWidget(label2);
    lay2->addWidget(edit2);

    QHBoxLayout *lay4=new QHBoxLayout();
    lay4->addWidget(btn1);
    lay4->addStretch();

    QVBoxLayout *lay3=new QVBoxLayout(this);
    lay3->addLayout(lay1);
    lay3->addLayout(lay2);
    lay3->addLayout(lay4);
    lay3->addWidget(label3);
    lay3->addWidget(text1);
}

//接收信息
void Widget::myrecvdata()
{
    //接收消息
    char buf[1024]={0};
    if(tcpsock->bytesAvailable()>0)
    {
        tcpsock->read(buf,sizeof(buf));
        if(strncmp(buf,"OK",2)==0)
        {
            text1->append("服务器返回OK!");
            //发送文件
            FILE *pfr=NULL;
            pfr=fopen(filename.toStdString().data(),"rb");
            if(pfr==NULL)
            {
                QMessageBox::critical(this,tr("错误信息"),"打开文件失败!");
                return;
            }
            int rc=0;
            while(!feof(pfr))
            {
                //
                memset(buf,0,sizeof(buf));
                rc=fread(buf,1,sizeof(buf),pfr);
                //发送数据
                tcpsock->write(buf,rc);
            }
            fclose(pfr);
            pfr=NULL;
            text1->append("文件发送成功!");
        }
    }

}

//获取文件名
void Widget::mygetfilename(const char *src,int len,char *dest)
{
    if(src==NULL||len==0||dest==NULL)
    {
        QMessageBox::critical(this,tr("错误信息"),"mygetfilename()参数不可以为空!");
        return;
    }
    int i=0;
    for(i=len-1;i>=0;i--)
    {
        if(src[i]=='/'||src[i]=='\\')
        {
            strcpy(dest,src+i+1);
            break;
        }
    }
}

//点击文件上传
void Widget::btn1_click()
{
    //获取IP地址
    QString ipaddr=edit1->text();
    if(ipaddr.isEmpty())
    {
        QMessageBox::critical(this,tr("错误信息"),"请填写IP地址!");
        return;
    }
    //获取端口号
    QString port=edit2->text();
    if(port.isEmpty())
    {
        QMessageBox::critical(this,tr("错误信息"),"请填写端口号!");
        return;
    }
    filename=QFileDialog::getOpenFileName();
    if(filename.isEmpty()) return;
    char buf[1024]={0};
    //获取文件名
    mygetfilename(filename.toStdString().data(),filename.toStdString().length(),buf);
    if(strlen(buf)==0)
    {
        QMessageBox::critical(this,tr("错误信息"),"文件格式不正确!");
        return;
    }
    tcpsock->close();
    //绑定端口号
    QHostAddress *serip=new QHostAddress();
    serip->setAddress(ipaddr);
    tcpsock->connectToHost(ipaddr,port.toInt());
    delete serip;
    //发送数据
    tcpsock->write(buf,strlen(buf));
    text1->append("开始发送数据!");
}

Widget::~Widget()
{

}