2014-04-04 Linux网络编程 - 基于TCP的文件传输
/*tcp_server.c*/
#include <stdio.h>
#include <stdlib.h>
#include <sys/socket.h>
#include <sys/types.h>
#include <unistd.h>
#include <arpa/inet.h>
#include <netinet/in.h>
#include <string.h>
#include <fcntl.h>
#include <pthread.h>
#define SIZE 5*1024*1024 //设置发送缓冲区大小
void* sendfile(void * arg) //线程负责发送文件
{
int fd_file ;
int fd_client = *(int*)arg ;
char send_buf[SIZE] ;
int readn ;
fd_file = open("../../../../Downloads/VMware-Workstation-Full-10.0.1-1379776.x86_64.bundle", O_RDONLY) ;
if(fd_file == -1)
{
perror("file open") ;
exit(-1) ;
}
while(memset(send_buf, 0, SIZE) , (readn = read(fd_file, send_buf, SIZE)) > 0)
{
printf("read from file : %d\n", readn) ; //一次读取的文件长度
int sendn = send(fd_client, send_buf, readn, 0) ; //send
printf("send to client : %d\n", sendn) ; //一次发送的文件长度
}
close(fd_file) ;
close(fd_client) ;
printf("send over !\n") ; //发送完成
pthread_exit(NULL) ;
}
int main(int argc, char * argv[]) // ---> ./exe [port]
{
int fd_server ;
pthread_t thd_send ;
fd_server = socket(AF_INET, SOCK_STREAM, 0) ; //socket
if(fd_server == -1)
{
perror("socket") ;
exit(-1) ;
}
struct sockaddr_in server_addr ;
memset(&server_addr, 0, sizeof(server_addr));
server_addr.sin_family = AF_INET ;
server_addr.sin_port = htons(atoi(argv[1])) ; //设置服务器端口号
server_addr.sin_addr.s_addr = INADDR_ANY;
if(-1 == bind(fd_server, (struct sockaddr*)&server_addr, sizeof(server_addr)))
{
perror("bind") ;
close(fd_server) ;
exit(-1) ;
}
listen(fd_server, 5) ; //监听端口是否有新的访问
while(1)
{
int fd_client = accept(fd_server, NULL, NULL) ; //accept
printf("a client connect !\n") ;
pthread_create(&thd_send, NULL, sendfile, (void*)&fd_client) ; //创建线程发送文件
}
close(fd_server) ;
return 0 ;
}
/*tcp_client.c*/
#include <stdio.h>
#include <stdlib.h>
#include <sys/socket.h>
#include <sys/types.h>
#include <unistd.h>
#include <arpa/inet.h>
#include <netinet/in.h>
#include <string.h>
#include <fcntl.h>
#define SIZE 5*1024*1024 //设置接收缓冲区大小
int main(int argc, char * argv[]) // ---> ./exe [ip] [port]
{
char recv_buf[SIZE] ;
int fd_client ;
fd_client = socket(AF_INET, SOCK_STREAM, 0) ; //socket
if(fd_client == -1)
{
perror("socket") ;
exit(-1) ;
}
struct sockaddr_in server_addr ;
memset(&server_addr, 0, sizeof(server_addr)) ;
server_addr.sin_family = AF_INET ;
server_addr.sin_port = htons(atoi(argv[2])) ;
server_addr.sin_addr.s_addr = inet_addr(argv[1]) ;
int iret = connect(fd_client, (struct sockaddr*)&server_addr, sizeof(server_addr)) ; //connect
if(iret == -1)
{
perror("connect") ;
close(fd_client) ;
exit(-1) ;
}
int fd_file = open("./a.out", O_WRONLY | O_CREAT, 0755) ;
if(fd_file == -1)
{
perror("file open") ;
exit(-1) ;
}
int nrecv ;
while(memset(recv_buf, 0, SIZE), (nrecv = recv(fd_client, recv_buf, SIZE, 0)) > 0) //recv
{
printf("recv from server : %d\n", nrecv) ;
int nwrite = write(fd_file, recv_buf, nrecv) ; //接收到的信息写入文件
printf("write to file : %d\n", nwrite) ;
}
printf("Download over~\n") ; //下载完成
close(fd_file) ;
close(fd_client) ;
return 0 ;
}