📄 client.c
字号:
#include <sys/socket.h>#include <netdb.h>#include <stdio.h>#include <string.h>#include <time.h>#include <malloc.h>#include <pthread.h>#define SERVER_PORT 8080 /*端口*/#define MAX_SIZE 5/*滑动窗口的大小*/#define PACKET_SIZE 1400 /*每次读取的大小*/#define FILE_SIZE 1024*1024*10+4typedef struct packet{ int number; /*包的编号,编号为0表示准备发送数据,编号为-1表示数据发送完毕*/ int length; /*包的数据的大小*/ char buffer[PACKET_SIZE]; /*每次读取1024个字节*/}packet_t;typedef struct packet_control_block{ packet_t *pt;/*包的指针,每次用malloc进行产生,成功发送后释放*/ /*int state;*//*包的状态---省略,在成功能发送就将其从Packet_State中删除即可*/ clock_t start;/*发送的起始时间,用以判断是否超时*/ int count; /*已被发送的次数,用以判断网络是否故障*/}PCB_t;typedef struct thread_parameter{ int i; FILE **fp; int sockfd; pthread_mutex_t *mutex; time_t start; struct sockaddr *addr_server;}paras_t;void recv_data(void *ps);PCB_t Packet_State[MAX_SIZE] = {0}; /*构建一PCB控制块,包含5个元素,即滑动窗口的大小*/int Wrtie_State = 0;/*当前文件的发送状态,是否发送完毕,以接受下一个请求*/int Current_Packet = 1;int main(){ int sockfd; if ((sockfd = socket(AF_INET, SOCK_DGRAM, 0)) == -1) { printf("socket error!!!\n"); return 1; } struct sockaddr_in addr_server; addr_server.sin_family = AF_INET; addr_server.sin_port = htons(SERVER_PORT); addr_server.sin_addr.s_addr = inet_addr("10.10.32.22"); FILE *fp = NULL; char buf_request[32] = {0}; time_t start = time(NULL); sendto(sockfd, "GET /test", sizeof("GET /test"), 0, (struct sockaddr*)&addr_server, sizeof(struct sockaddr)); paras_t **ps = (paras_t **)malloc(sizeof(paras_t *)); int count = MAX_SIZE; pthread_mutex_t mutex; pthread_mutex_init(&mutex, NULL); int i = 0; for (;i < MAX_SIZE;i++) { ps[i] = (paras_t*)malloc(sizeof(paras_t)); ps[i]->i = i; ps[i]->fp = &fp; ps[i]->start = start; ps[i]->mutex = &mutex; ps[i]->sockfd = sockfd; ps[i]->addr_server = (struct sockaddr*) & addr_server; pthread_t pt; pthread_create(&pt, NULL, (void *)recv_data, (void *)ps[i]); pthread_detach(pt); } while (1) { i = 0; char ch; memset(buf_request, '\0', 32); for (;(ch = getchar()) != '\n';i++) { buf_request[i] = ch; } sendto(sockfd, buf_request, strlen(buf_request), 0, (struct sockaddr*)&addr_server, sizeof(struct sockaddr)); } for (i = 0;i < MAX_SIZE;i++) { free(ps[i]); } free(ps); return 0;}void recv_data(void *ps){ int i = ((paras_t *)ps)->i; FILE **fp = ((paras_t *)ps)->fp; int sockfd = ((paras_t *)ps)->sockfd; pthread_mutex_t *mutex = ((paras_t *)ps)->mutex; time_t start = ((paras_t *)ps)->start; struct sockaddr addr_server = *(((paras_t *)ps)->addr_server); packet_t *pt = (packet_t *)malloc(sizeof(packet_t));/*每次重写入数据后不进行free*/ while (1) { if (recvfrom(sockfd, pt, sizeof(packet_t), 0, NULL, NULL) <= 0) { printf("recvfrom error!!!\n"); return; } if (Wrtie_State && pt->number != -1) { //pthread_mutex_lock(mutex); /*int offset = (pt->number - 1) * PACKET_SIZE; if (fseek(*fp, offset, SEEK_SET)) { printf("fseek error!!!\n"); return; }*/ int length = fwrite(pt->buffer, 1, pt->length, *fp); //pthread_mutex_unlock(mutex); printf("the %d block has been received!!!", pt->number); printf("the length is %d!!!\n\n", length); char ack[16] = {0}; sprintf(ack, "ACK %d", pt->number); sendto(sockfd, ack, sizeof(ack), 0, &addr_server, sizeof(struct sockaddr)); time_t end = time(NULL); printf("have yongshi %d\n", (end - start)); } else { if (pt->number == 0) { char buf_filename[32] = {0}; memcpy(buf_filename, "./file_write", strlen("./file_write")); memcpy(buf_filename + strlen("./file_write"), "/test", sizeof("/test")); if ((*fp = fopen(buf_filename, "wb")) == NULL) { printf("fopen error!!!\n"); return; } /*printf("please wait...\n"); for (i = 0 ; i < FILE_SIZE; i++) { fwrite(&i, 4, 1, *fp); }*/ Wrtie_State = 1; } else if (pt->number == -1) { fclose(*fp); pt = NULL; Wrtie_State = 0; break; } } } free(pt); pt = NULL;}
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -