利用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() { }