⭐ 欢迎来到虫虫下载站! | 📦 资源下载 📁 资源专辑 ℹ️ 关于我们
⭐ 虫虫下载站

📄 client.c

📁 Linux下网络编程
💻 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 + -