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.X.XXX";
const char *file_name = "Recv_file";
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, "w");
if (fp == NULL)
{
perror("fopen failed: ");
return NULL;
}
return fp;
}
int main()
{
int size;
FILE* cli_fp;
char buff[4]; // --接收数据长度, 后续根据开辟相应空间大小
memset(buff, 0, sizeof(buff));
// 初始化接收套接字
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");
// 接收消息头
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);
// 接收正文
int ret = recv_message(sock_cli, ar, len);
if (ret < 0)
{
printf("recv_message failed.\n");
return -1;
}
// 写入新文件
fwrite(ar, 1, len, cli_fp);
printf("write to file succ.\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_PATH = "file_name";
const char *FILE_PATH = "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_PATH, "r"); // 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, size;
char *send_buf;
// 打开文件,得到文件大小
size = get_file_size();
printf("len: %d\n", size);
// 开辟空间,存放升级文件
send_buf = malloc_save(size);
printf("file text: %s\n", send_buf + sizeof(Data_t));
// 初始化sockfd,并等待客户端连接
ret = socket_handler();
if (ret != 0)
{
printf("socket_handler failed\n");
return -1;
}
// 发送文件
while(1)
{
printf("Now to upload versiom, please input Y(y)\n");
if ('y' == getchar() || 'Y' == getchar())
{
ret = send_message(conn, send_buf, size + sizeof(Data_t));
if (ret < 0){
printf("send_message failed\n");
break;
}
}
printf("send client.. over\n");
}
fclose(fp);
free(send_buf);
close(conn);
close(server_sockfd);
return 0;
}