/*server_func.h*/
#ifndef SERVER_H
#define SERVER_H
#include
#include
#include
#include
#include
#include
#include
#include
#include
#include
#include
#define MAX_CON 10
#define MAX_SIZE 1024
#define CMD_EXIT "exit"
#define CMD_DOWNLOAD_FILE "df"
typedef enum tagCmdID
{
CMD_INVALID = -1,
CMD_FILE_EXIST,
CMD_FILE_NOT_EXIST
}E_CMD_ID;
typedef struct tagClientCom
{
E_CMD_ID cmd_id;
long length;
}T_CLIENT_COM_HEADER;
typedef struct
{
int sfd;
int cfd;
char filename[128];
}tcp_info;
int tcp_init(const char* ip, int port);
int tcp_accept(int sfd);
void * send_file(void * arg);
void * pthread_recv(void *arg);
void signalhandler(void);
#endif
/*server_func.c*/
#include "server_func.h"
int tcp_init(const char* ip, int port) //用于初始化
{
int on = 1;
int sfd = socket(AF_INET, SOCK_STREAM, 0); //首先建立一个Socket,向系统申请
if(sfd == -1)
{
printf("socket error: %s\n", strerror(errno));
return -1;
}
int ret = setsockopt( sfd, SOL_SOCKET, SO_REUSEADDR, &on, sizeof(on) );
if(ret < 0)
{
printf("setsockopt error: %s", strerror(errno));
}
struct sockaddr_in serveraddr;
memset( &serveraddr, 0, sizeof(struct sockaddr) );
serveraddr.sin_family = AF_INET;
serveraddr.sin_port = htons(port);
serveraddr.sin_addr.s_addr = INADDR_ANY; //或者INADDR_ANY
if(bind(sfd, (struct sockaddr*)&serveraddr, sizeof(struct sockaddr)) == -1)
{
printf("Bind error: %s\n", strerror(errno));
close(sfd);
return -1;
}
if(listen(sfd, MAX_CON) == -1) //监听它 最大连接数为10
{
printf("Listen error: %s\n", strerror(errno));
close(sfd);
return -1;
}
return sfd;
}
int tcp_accept(int sfd)
{
struct sockaddr_in clientaddr;
int addrlen = sizeof(struct sockaddr);
int new_fd = accept(sfd, (struct sockaddr*)&clientaddr, &addrlen);
memset(&clientaddr, 0, addrlen);
if(new_fd == -1)
{
printf("accept error: %s\n", strerror(errno));
sleep(1);
return -1;
}
printf("Client%d(%s %d) success connect...\n", new_fd, inet_ntoa(clientaddr.sin_addr), ntohs(clientaddr.sin_port));
return new_fd;
}
void * send_file(void * arg)
{
int needSend = sizeof(T_CLIENT_COM_HEADER);
char *head = (char*)malloc(needSend);
char buffer[MAX_SIZE];
T_CLIENT_COM_HEADER *com = (T_CLIENT_COM_HEADER*)malloc(sizeof(T_CLIENT_COM_HEADER));
tcp_info *client_info;
client_info = ( tcp_info *)arg;
com->length = needSend;
memset(buffer, 0, sizeof(buffer));
if(access(client_info->filename, F_OK) >= 0)
{
FILE *fp = fopen(client_info->filename, "r");
fseek(fp, 0L, SEEK_END);
long file_size = ftell(fp);
rewind(fp);
com->length += file_size;
com->cmd_id = CMD_FILE_EXIST;
memcpy(head, com, needSend);
int sendlength = send(client_info->cfd, head, needSend, 0);
printf("head->cmd_id = %d, head->length = %ld\n", com->cmd_id, com->length);
do
{
int file_block_length = fread(buffer, sizeof(char), MAX_SIZE, fp);
int len = send(client_info->cfd, buffer, file_block_length, 0);
if(file_block_length <= 0)
{
break;
}
bzero(buffer, sizeof(buffer));
}while(1);
fclose(fp);
printf("File:\t%s \nTransfer Finished!\n", client_info->filename);
}
else
{
com->cmd_id = CMD_FILE_NOT_EXIST;
memcpy(head, com, needSend);
int sendlength = send(client_info->cfd, head, needSend, 0);
}
}
void* pthread_recv(void *arg)
{
char buf[128] = {0};
tcp_info *client_info;
client_info = ( tcp_info *)arg;
memset(buf, 0, sizeof(buf));
while(1)
{
char commond[64];
char filename[128];
int ret = recv(client_info->cfd, buf, sizeof(buf), 0 );
if (ret < 0)
{
printf("receive error: %s\n", strerror(errno));
break;
}
else if(ret == 0)
{
printf("Client%d(Exception) exit!\n", client_info->cfd);
break;
}
if(0 == strcmp(buf, CMD_EXIT))
{
printf("Client%d exit!\n", client_info->cfd);
break;
}
if((sscanf(buf, "%s %s", commond, filename) != 0) && (0 == strcmp(commond, CMD_DOWNLOAD_FILE)))
{
pthread_t pid;
int ret;
int length = 0;
strcpy(client_info->filename, filename);
ret = pthread_create(&pid, NULL, send_file, (void*)client_info);
continue;
}
printf("Client%d: %s\n", client_info->cfd, buf);
}
close(client_info->cfd);
free(client_info);
pthread_exit(NULL);
}
void signalhandler(void)
{
sigset_t sigSet;
sigemptyset(&sigSet);
sigaddset(&sigSet,SIGINT);
sigaddset(&sigSet,SIGQUIT);
sigaddset(&sigSet,SIGPIPE);
sigprocmask(SIG_BLOCK,&sigSet,NULL);
}
/*server.c*/
#include "server_func.h"
int main(int argc,char **argv)
{
int ret_send;
int ret_recv;
int sfd;
int cfd;
sfd = tcp_init("192.168.20.217", 1234);
if(-1 == sfd)
{
return 0; }
signalhandler();
do
{
pthread_t id2;
tcp_info *info;
cfd = tcp_accept(sfd);
if(cfd < 0)
{
continue;
}
info = (tcp_info*)malloc(sizeof(tcp_info));
info->sfd = sfd;
info->cfd = cfd;
ret_recv = pthread_create(&id2, NULL, pthread_recv, (void*)info);
if(ret_recv != 0)
{
printf("create pthread error!\n");
}
}while(1);
close(cfd);
close(sfd);
return 0;
}
/*client_func.h*/
#ifndef CLIENT_H
#define CLIENT_H
#include
#include
#include
#include
#include
#include
#include
#include
#include
#include
#include
#include
#define MAX_SIZE 1024
#define CMD_EXIT "exit"
#define CMD_DOWNLOAD_FILE "df"
typedef enum tagCmdID
{
CMD_INVALID = -1,
CMD_FILE_EXIST,
CMD_FILE_NOT_EXIST
}E_CMD_ID;
typedef struct tagClientCom
{
E_CMD_ID cmd_id;
long length;
}T_CLIENT_COM_HEADER;
typedef struct
{
int cfd;
char filename[128];
}file_information;
int tcp_connect(const char* ip, int port);
void* recv_file(void *arg);
void* pthread_send(void *arg);
#endif
/*client_func.c*/
#include "client_func.h"
int tcp_connect(const char* ip, int port)
{
int sfd = socket(AF_INET, SOCK_STREAM, 0);
if(sfd == -1)
{
printf("socket error: %s", strerror(errno));
return -1;
}
struct sockaddr_in serveraddr;
memset(&serveraddr, 0, sizeof(struct sockaddr) );
serveraddr.sin_family = AF_INET;
serveraddr.sin_port = htons(port);
serveraddr.sin_addr.s_addr = inet_addr(ip);
if(connect(sfd, (struct sockaddr*) &serveraddr, sizeof(struct sockaddr)) == -1 )
{
printf("connect error: %s", strerror(errno));
close(sfd);
return -1;
}
return sfd;
}
void* recv_file(void *arg)
{
int needRecv = sizeof(T_CLIENT_COM_HEADER);
int length = 0;
long pos = 0;
char *head = (char*)malloc(needRecv);
char buffer[MAX_SIZE];
file_information *file_info;
T_CLIENT_COM_HEADER *myNode = (T_CLIENT_COM_HEADER*)malloc(sizeof(T_CLIENT_COM_HEADER));
file_info = ( file_information *)arg;
char *filename = basename(file_info->filename);
memset(&buffer, 0, MAX_SIZE);
while(pos < needRecv)
{
length = recv(file_info->cfd, head+pos, needRecv, 0);
if (length < 0)
{
printf("Server Recieve Data Failed!\n");
break;
}
pos += length;
}
memcpy(myNode,head,needRecv);
if(myNode->cmd_id == CMD_FILE_EXIST)
{
printf("File %s is sending...\n", filename);
filename = NULL;
FILE *fp = fopen(file_info->filename, "w");
length = 0;
pos = 0;
if (fp == NULL)
{
printf("File:\t%s Can Not Open To Write!\n", file_info->filename);
return;
}
while(pos < myNode->length - needRecv)
{
int write_length;
length = recv(file_info->cfd, buffer, MAX_SIZE, 0);
if (length < 0)
{
printf("Recieve Data From Server Failed!\n");
break;
}
pos += length;
write_length = fwrite(buffer, sizeof(char), length, fp);
if (write_length < length)
{
printf("File:\t%s Write Failed!\n", file_info->filename);
break;
}
bzero(buffer, MAX_SIZE);
}
printf("Recieve File: %s\tFrom Server Finished!\n", file_info->filename);
fclose(fp);
}
else if(myNode->cmd_id == CMD_FILE_NOT_EXIST)
{
printf("File %s is not exist!\n", file_info->filename);
}
free(head);
free(myNode);
}
void* pthread_send(void *arg)
{
int *temp;
char buf[128];
memset(buf, 0, sizeof(buf));
temp = (int *)arg;
while(1)
{
char commond[64];
char filename[128];
char save_path[128];
int arg_cont;
gets(buf);
if(-1 == send(*temp, buf, sizeof(buf), 0))
{
printf("send error: %s", strerror(errno));
close(*temp);
return;
}
if(0 == strcmp(buf, CMD_EXIT))
{
break;
}
if(((arg_cont = sscanf(buf, "%s %s %s", commond, filename, save_path)) != 0) && (0 == strcmp(commond, CMD_DOWNLOAD_FILE)))
{
if(arg_cont != 3)
{
printf("parameter error!\n");
continue;
}
file_information *file_info;
pthread_t pid;
int ret;
file_info = (file_information *)malloc(sizeof(file_information));
memset(file_info, 0, sizeof(file_information));
strcpy(file_info->filename, save_path);
file_info->cfd = *temp;
ret = pthread_create(&pid, NULL, (void*)recv_file, (void*)file_info);
if(ret != 0)
{
printf("create pthread error!\n");
}
}
}
close(*temp);
pthread_exit(NULL);
}
/*client.c*/
#include "client_func.h"
int main(int argc,char **argv)
{
int ret_send;
pthread_t id1;
int sfd = tcp_connect("192.168.20.217", 1234);
int *p_sfd = &sfd;
ret_send = pthread_create(&id1, NULL, (void*)pthread_send, (void*)p_sfd);
if(ret_send != 0)
{
printf("create pthread error!\n");
}
else
{
pthread_join(id1, NULL);
}
close(sfd);
return 0;
}
客户端1:
客户端2:
这是一个demo仅用来学习~
下面是传输文件运行截图,可以用来传输比较大的文件,试过传输3G多的文件:
后面加上makefile:
.PHONY : clean server
#server: client server.c
# gcc server.c -o server -lpthread
#client: client.c
# gcc client.c -o client -lpthread
#clean:
# pkill -9 server
# pkill -9 client
# rm server client
GCCTV = arm-linux-androideabi-gcc
GCC = gcc
object = server_func.o server.o client_func.o client.o
LFLAG = -lpthread
#LFLAG = -pie -fPIE
server : server.o server_func.o client
$(GCC) -o server server.o server_func.o $(LFLAG)
server.o : server.c
$(GCC) -c server.c $(LFLAG)
server_func.o : server_func.c
$(GCC) -c server_func.c $(LFLAG)
client : client.o client_func.o
$(GCC) -o client client.o client_func.o -lpthread
client.o : client.c
$(GCC) -c client.c -lpthread
client_func.o : client_func.c
$(GCC) -c client_func.c -lpthread
clean:
rm $(object)