socket通信 UDP文件传输(多客户端)——附源码
来源:互联网 发布:c 并发编程 书籍 编辑:程序博客网 时间:2024/06/09 15:21
程序需求:
- 程序分为server程序和client程序,通讯由client主动发起请求一个指定的文件,由server传文件给client。
- 一个server可以支持多个client通信。
- 数据包要有校验机制。
- 有丢包重传机制。
- 支持断点续传。
- 能正常处理各种异常现象。
实现过程
服务器
一、制定UDP通信协议
设计一个UDP报头
type len id check data
1、type(数据类型):char
给出这个UDP包的数据类型及服务器的处理方式。我现在把它分为不同的几个值:文件传输申请,客户端收到一个数据包后的确认(重传、继续)
断点续传(掉线后重新建立连接并接着以前的传输),文件件传输结束(服务器到客户端),文件传输错误,等。
2、len(数据包长度):int
3、check(校验和):int
对包进行CRC校验和,防止数据传输过程中错误。
4、id(标识):long int
对文件传输时对数据包进行标号,在断点续传时标识文件断点位置,等(根据type需求改变)
二、服务器事件处理机制
一开始我准备使用一个链表来接收保存客户端的请求、再用一个链表队列来处理相应的请求(另一个处理线程)、还有一个超时处理队列。最后发现变得很复杂(对链表操作不是很熟练)。决定只用一个全局数组来代替上面三个链表的功能。
开两个线程一个用于循环接收客户端发来的数据,并进行分类标记放入数组中,另一个线程用于处理数组中待处理的事件。(一个客户端一个数组元素)
每个客户端分配一个结构体并放入数组中。
客户 结构体:flag (标识)、clinet_addr(客户端地址)、timer(时间)、struct file_info(文件信息)、等
flag:标记客户端状态(等待传输、服务器等待反映、已经超时、空客户端等)
timer:记录客户端最后反映的时刻、用于判断超时。
file_info:(文件路径,文件指针,文件偏移量)记录文件传输情况。
主线程中循环判断是否有客户端连接超时。
客户端
向服务器申请文件(先判断是否断点),当断点重传时,用fseek函数找到断点,并把断点信息发给服务器端,服务器重断点处重新读取文件开始传输。发出请求后等待服务器答复,服务器答复后开始计数接受文件包。服务器给每个包编上编号,客户端每接收一个udp包放到缓冲区中,当缓冲区慢后就按包编号顺序写到文件中记录编号。当没有要写的编号时,给服务器发送重发这个包ACK。
头文件
#include <sys/socket.h>
#include <string.h>
#include <netinet/in.h>
#include <stdio.h>
#include <fcntl.h>
#include <time.h>
#include <strings.h>
#include <sys/stat.h>
#include <stdlib.h>
#include <unistd.h>
#include <sys/select.h>
#include <sys/time.h>
#include <sys/types.h>
/*udp_datapack->type*/
#define REQ_FILE 0
#define ACK_TRUE 1
#define ACK_FAIL 2
#define ACK_RECONNECT 3
#define FILE_DATE 4
/*udp_req->flag udp类型*/
#define CLINET_EMPTY 0
#define CLINET_FIRST_REQ 1
#define CLINET_TIME_OUT 2
#define CLINET_LINK_ACK_WAIT 3
#define CLINET_LINK_ACK_TRUE 4
#define CLINET_LINK_ACK_FAIL 5
/*send_ack flag. 当udp为ACK时 udp头中label的值*/
/*udp_datapack->type=ACK_TRUE | ACK_FAIL ===> udp_datapack->label */
#define SERVER_CLINET_FULL 0
#define FIND_FILE 1
#define UNFIND_FILE 2
#define FILE_OVER 3
#define TYPE_UNRECOGNIZED 4
#define CRC_FAIL 5
#define FILE_READ_FAIL 6
/*clinet file flag(file_pack_num) */
#define FILE_COMPLETE -1
#define FILE_INCOMPLETE -2
#define SERVER_BUSY -3
#define FILE_NOT_EXIST -4
#define FILE_SERV_READ_FAIL -5
#define RE_APPLY -6
#define SERV_PORT 8888 /*端口号*/
#define MAX 1024 /*udp数据部分大小*/
#define MAX_UDP_CLINET 10 /*服务器处理客户端最大量*/
#define UDP_HEAD_LEN 13 /*udp头大小*/
#define TIMEVAL 45 /*超时时间*//*udp包格式定义*/
struct udp_datapack{
char type; /*数据包类型*/
long int label;/*文件包号、请求包文件位置信息*/
int size; /*包大小*/
int check; /*CRC*/
char data[MAX];
};
/*传输的文件信息*/
struct file_infor{
char *file_path;
FILE * file_fp;
off_t seek_flag;
};
/*服务器保存的客户端信息*/
struct udp_req{
char flag; /*客户端状态*/
int fsend_label;/*跟据flag变化*/
struct sockaddr_in req_addr;/*客户端地址*/
struct file_infor req_file;/*客户所请求的文件信息*/
struct timeval timeout;/*超时计时*/
};
/*本地socket信息*/
struct local_infor{
int sockfd;
struct sockaddr_in local_addr;
};
完整源码下载地址:http://download.csdn.net/user/jmq_0000
- socket通信 UDP文件传输(多客户端)——附源码
- Socket(Udp)通信客户端
- Linux网络编程——UDP通信(文件传输)
- UDP——socket通信
- TCP socket多客户端文件传输
- Java 基于 UDP 实现 Socket中的多客户端通信
- Java 基于 UDP 实现 Socket中的多客户端通信
- Socket UDP通信小结(指定客户端的接受端口)
- C#UDP通信+文件传输
- 循序渐进Socket网络编程(多客户端、信息共享、文件传输)
- 循序渐进Socket网络编程(多客户端、信息共享、文件传输)
- 循序渐进Socket网络编程(多客户端、信息共享、文件传输)
- 循序渐进Socket网络编程(多客户端、信息共享、文件传输)
- Socket网络编程(多客户端、信息共享、文件传输)
- socket编程(3)—— UDP协议通信
- java socket编程——UDP通信
- Windows Socket安全通信(附C++源码)
- 浅谈java socket通信,并附源码
- static_cast
- 写了一个狠龊的function,从listA中取出不同于listB的数据
- 架构如何才能抵制熵增
- Service Broker - Internal Dynamic Views
- 咖啡豆(JavaBean)·JSP中使用JavaBean
- socket通信 UDP文件传输(多客户端)——附源码
- 浅谈Android系统进程间通信(IPC)机制Binder中的Server和Client获得Service Manager接口之路
- jdk中String对象的replace和replaceAll方法
- java中关键字:static
- POJ-2559 维护单调栈.细节阿细节
- 差分约束——HDOJ 1529
- 完美解决:xcode4.2 修改__MyCompanyName__,终于让我找到方法了
- 敏捷开发一千零一问系列之十二:敏捷实施的步骤?
- Win7 RTM及win v pc RC体验