網路傳輸檔案 -- 迴圈傳送檔案
阿新 • • 發佈:2018-11-08
fread
FILE *fopen(const char *path, const char *mode);
size_t fread(void *ptr, size_t size, size_t nmemb, FILE *stream);
size_t fwrite(const void *ptr, size_t size, size_t nmemb,
FILE *stream);
- 第二個引數:型別,每個元素size個位元組
- 第三個引數count是讀取的資料個數,資料大小為自己的第二個引數size的值。即讀取count個size大小的資料。
-
返回值:
- 正常:返回實際讀取到的元素個數
- 檔案尾:return 0
- 非正常:return 0。
-
一般就用
- char buffer[1024] = {‘\0’};
- fread(buffer,1,sizeof(buffer),fp);
int open(const char *pathname, int flags, mode_t mode); ssize_t read(int fd, void *buf, size_t count); ssize_t write(int fd, const void *buf, size_t count);
- fd:檔案描述符,用來指向要操作的檔案的檔案結構體
- buf:一塊記憶體空間
- count:希望讀取的位元組數
- 返回值
- 正常:表示實際讀到的位元組數(字串結束符 ‘\0’不算)
- 讀到檔案尾/套接字被被關閉:return 0
- 發生錯誤:return -1
- 一般就用
- char buffer[1024] = {‘\0’};
- read(fd,buffer,sizeof(buffer));
client.c
#include <sys/types.h> #include <sys/socket.h> #include <stdio.h> #include <netinet/in.h> #include <arpa/inet.h> #include <unistd.h> #include <string.h> #include <stdlib.h> #include <fcntl.h> #include <sys/shm.h> #define MYPORT 9191 #define BUFFER_SIZE 1024 char* SERVER_IP = "xxx.xxx.xxx.xxx"; const char *file_name = "v06"; int sock_cli; struct Data_s { int len; } __attribute__ ((__packed__)); typedef struct Data_s Data_t; int recv_message(int sockfd, char *buf, int len) { int count = 0, ret; for (; ;) { ret = recv(sockfd, buf + count, len - count, 0); if (ret == 0) { perror ("recv failed."); return -1; } count += ret; if (count == len) { break; } } return 0; } int init_sockfd() { int sockfd = socket(AF_INET,SOCK_STREAM, 0); return sockfd; } int connect_server() { ///定義sockaddr_in struct sockaddr_in servaddr; memset(&servaddr, 0, sizeof(servaddr)); servaddr.sin_family = AF_INET; servaddr.sin_port = htons(MYPORT); ///伺服器埠 servaddr.sin_addr.s_addr = inet_addr(SERVER_IP); ///伺服器ip if (connect(sock_cli, (struct sockaddr *)&servaddr, sizeof(servaddr)) < 0) { perror("connect"); return -1; } return 0; } FILE *open_new_file() { FILE *fp = fopen(file_name, "wb"); if (fp == NULL) { perror("fopen failed: "); return NULL; } return fp; } int main() { int size, data_len; int flag; FILE* cli_fp; char buffer[BUFFER_SIZE]; // --接收資料長度, 後續根據開闢相應空間大小 memset(buffer, 0, sizeof(buffer)); // 初始化接收套接字 sock_cli = init_sockfd(); printf("connect %s:%d\n",SERVER_IP,MYPORT); // 初始化檔案指標 cli_fp = open_new_file(); // 連線伺服器,成功返回0,錯誤返回-1 if (connect_server() < 0) { printf("connect server failed\n"); return -1; } printf("connect server success\n"); #if 0 // 接收訊息頭 recv_message(sock_cli, buff, sizeof(Data_t)); Data_t *mydata = (Data_t *)buff; // 根據頭訊息中長度,開闢相應大小空間 int len = ntohl(mydata->len); printf("trans data = %d\n", len); char *ar = (char *)malloc(len); memset(ar, 0, len); #endif // 接收正文 //while(data_len = recv_message(sock_cli, buffer, BUFFER_SIZE)) while(data_len = recv(sock_cli, buffer, BUFFER_SIZE, 0)) { //printf("data recving.. buffer is %s\tdata_len = %d\n", buffer, data_len); printf("data recving.. data_len = %d\n", data_len); flag++; if (flag == 1) printf("data recving...\n"); if (data_len == 0) { printf("receive err!\r\n"); return -1; } int write_len = fwrite(buffer, sizeof(char), data_len, cli_fp); if (write_len > data_len) { printf("write data to file failed\n"); return -1; } bzero(buffer, BUFFER_SIZE); } if (flag > 0) printf("transmit over.\n"); else if(flag == 0) printf("transmit failed.\n"); //free(ar); //ar = NULL; fclose(cli_fp); close(sock_cli); return 0; }
server.c
#include <sys/types.h>
#include <sys/socket.h>
#include <stdio.h>
#include <netinet/in.h>
#include <arpa/inet.h>
#include <unistd.h>
#include <string.h>
#include <stdlib.h>
#include <fcntl.h>
#include <sys/shm.h>
#include <sys/stat.h>
#include <fcntl.h>
int server_sockfd;
int conn;
struct Data_s{
int length;
} __attribute__ ((__packed__));
typedef struct Data_s Data_t;
#define MYPORT 9191
#define QUEUE 20
#define BUFFER_SIZE 1024
const char *FILE_NAME = "V06";
//const char *FILE_NAME = "1.c";
FILE *fp;
int send_message(int sockfd, char *buf, int len)
{
int count = 0, ret;
for (; ;)
{
ret = send(sockfd, buf + count, len - count, 0);
if (ret == 0)
{
perror("send failed");
return -1;
}
count += ret;
if (count == len)
{
break;
}
}
return 0;
}
int socket_handler()
{
server_sockfd = socket(AF_INET,SOCK_STREAM, 0);
int on = 1;
int ret = setsockopt(server_sockfd, SOL_SOCKET, SO_REUSEADDR, (char *)&on, sizeof(on));
if (ret < 0)
{
perror("setsockopt failed");
return -1;
}
///定義sockaddr_in
struct sockaddr_in server_sockaddr;
server_sockaddr.sin_family = AF_INET;
server_sockaddr.sin_port = htons(MYPORT);
server_sockaddr.sin_addr.s_addr = htonl(INADDR_ANY);
///bind,成功返回0,出錯返回-1
if(bind(server_sockfd,(struct sockaddr *)&server_sockaddr,sizeof(server_sockaddr))==-1)
{
perror("bind");
exit(1);
}
printf("listen port %d\n",MYPORT);
///listen,成功返回0,出錯返回-1
if(listen(server_sockfd,QUEUE) == -1)
{
perror("listen");
exit(1);
}
///客戶端套接字
struct sockaddr_in client_addr;
socklen_t length = sizeof(client_addr);
printf("wait to client.. \n");
///成功返回非負描述字,出錯返回-1
conn = accept(server_sockfd, (struct sockaddr*)&client_addr, &length);
if(conn<0)
{
perror("connect");
exit(1);
}
printf("client connect succees!!\n");
return 0;
}
int get_file_size()
{
int size;
fp = fopen(FILE_NAME, "rb"); // rb 二進位制 rt 文字檔案 r+ 可讀可寫
if (fp == NULL)
{
perror("fopen failed: ");
return -1;
}
fseek(fp, 0, SEEK_END);
size = ftell(fp);
rewind(fp); // 重定向到檔案開頭
return size;
}
char *malloc_save(int size)
{
// 存放檔案大小及內容
char *send_buf = (char *)malloc(sizeof(char) * size + sizeof(int));
memset(send_buf, 0, sizeof(send_buf));
Data_t *data = (Data_t *)send_buf;
data->length = htonl(size);
char *file_data = send_buf + sizeof(Data_t);
fread(file_data, 1, size, fp);
return send_buf;
}
int main()
{
int ret, len;
char buffer[BUFFER_SIZE];
memset(buffer, 0, sizeof(buffer));
//char *send_buf;
#if 0
// 開啟檔案,得到檔案大小
size = get_file_size();
printf("len: %d\n", size);
// 開闢空間,存放升級檔案
send_buf = malloc_save(size);
printf("file text: %s\n", send_buf + sizeof(Data_t));
#endif
// 初始化sockfd,並等待客戶端連線
ret = socket_handler();
if (ret != 0)
{
printf("socket_handler failed\n");
return -1;
}
// 開啟檔案
FILE *fp = fopen(FILE_NAME, "rb");
if (fp == NULL)
{
printf("the file was not open!\n");
return -1;
}
printf("open file succ, And transmit data after 5s ..\n");
sleep(5);
// 傳送檔案
/*while(!feof(fp)) // return !0 show file is eof*/
/*{ */
/*len = fread(buffer, 1, 1024, fp);*/
while((len = fread(buffer, 1, 1024, fp)) > 0){
//printf("len = %d\n", len);
//if (send_message(conn, buffer, len) < 0)
if (send(conn, buffer, len, 0) < 0)
{
printf("send_message failed\n");
break;
}
bzero(buffer, BUFFER_SIZE);
}
printf("data transmit end!\n");
fclose(fp);
//free(send_buf);
close(conn);
close(server_sockfd);
return 0;
}