Linux网络编程之socket文件传输示例
本文所述示例程序是基于Linux平台的socket网络编程,实现文件传输功能。该示例是基于TCP流协议实现的socket网络文件传输程序。采用C语言编写。最终能够实现传输任何格式文件的文件传输程序。
具体实现代码如下:
Server端代码如下:
/************************************************************************* >FileName:Server.c >Author:SongLee ************************************************************************/ #include<netinet/in.h>//sockaddr_in #include<sys/types.h>//socket #include<sys/socket.h>//socket #include<stdio.h>//printf #include<stdlib.h>//exit #include<string.h>//bzero #defineSERVER_PORT8000 #defineLENGTH_OF_LISTEN_QUEUE20 #defineBUFFER_SIZE1024 #defineFILE_NAME_MAX_SIZE512 intmain(void) { //声明并初始化一个服务器端的socket地址结构 structsockaddr_inserver_addr; bzero(&server_addr,sizeof(server_addr)); server_addr.sin_family=AF_INET; server_addr.sin_addr.s_addr=htons(INADDR_ANY); server_addr.sin_port=htons(SERVER_PORT); //创建socket,若成功,返回socket描述符 intserver_socket_fd=socket(PF_INET,SOCK_STREAM,0); if(server_socket_fd<0) { perror("CreateSocketFailed:"); exit(1); } intopt=1; setsockopt(server_socket_fd,SOL_SOCKET,SO_REUSEADDR,&opt,sizeof(opt)); //绑定socket和socket地址结构 if(-1==(bind(server_socket_fd,(structsockaddr*)&server_addr,sizeof(server_addr)))) { perror("ServerBindFailed:"); exit(1); } //socket监听 if(-1==(listen(server_socket_fd,LENGTH_OF_LISTEN_QUEUE))) { perror("ServerListenFailed:"); exit(1); } while(1) { //定义客户端的socket地址结构 structsockaddr_inclient_addr; socklen_tclient_addr_length=sizeof(client_addr); //接受连接请求,返回一个新的socket(描述符),这个新socket用于同连接的客户端通信 //accept函数会把连接到的客户端信息写到client_addr中 intnew_server_socket_fd=accept(server_socket_fd,(structsockaddr*)&client_addr,&client_addr_length); if(new_server_socket_fd<0) { perror("ServerAcceptFailed:"); break; } //recv函数接收数据到缓冲区buffer中 charbuffer[BUFFER_SIZE]; bzero(buffer,BUFFER_SIZE); if(recv(new_server_socket_fd,buffer,BUFFER_SIZE,0)<0) { perror("ServerRecieveDataFailed:"); break; } //然后从buffer(缓冲区)拷贝到file_name中 charfile_name[FILE_NAME_MAX_SIZE+1]; bzero(file_name,FILE_NAME_MAX_SIZE+1); strncpy(file_name,buffer,strlen(buffer)>FILE_NAME_MAX_SIZE?FILE_NAME_MAX_SIZE:strlen(buffer)); printf("%s\n",file_name); //打开文件并读取文件数据 FILE*fp=fopen(file_name,"r"); if(NULL==fp) { printf("File:%sNotFound\n",file_name); } else { bzero(buffer,BUFFER_SIZE); intlength=0; //每读取一段数据,便将其发送给客户端,循环直到文件读完为止 while((length=fread(buffer,sizeof(char),BUFFER_SIZE,fp))>0) { if(send(new_server_socket_fd,buffer,length,0)<0) { printf("SendFile:%sFailed./n",file_name); break; } bzero(buffer,BUFFER_SIZE); } //关闭文件 fclose(fp); printf("File:%sTransferSuccessful!\n",file_name); } //关闭与客户端的连接 close(new_server_socket_fd); } //关闭监听用的socket close(server_socket_fd); return0; }
Client端代码如下:
/************************************************************************* >FileName:Client.c >Author:SongLee ************************************************************************/ #include<netinet/in.h>//sockaddr_in #include<sys/types.h>//socket #include<sys/socket.h>//socket #include<stdio.h>//printf #include<stdlib.h>//exit #include<string.h>//bzero #defineSERVER_PORT8000 #defineBUFFER_SIZE1024 #defineFILE_NAME_MAX_SIZE512 intmain() { //声明并初始化一个客户端的socket地址结构 structsockaddr_inclient_addr; bzero(&client_addr,sizeof(client_addr)); client_addr.sin_family=AF_INET; client_addr.sin_addr.s_addr=htons(INADDR_ANY); client_addr.sin_port=htons(0); //创建socket,若成功,返回socket描述符 intclient_socket_fd=socket(AF_INET,SOCK_STREAM,0); if(client_socket_fd<0) { perror("CreateSocketFailed:"); exit(1); } //绑定客户端的socket和客户端的socket地址结构非必需 if(-1==(bind(client_socket_fd,(structsockaddr*)&client_addr,sizeof(client_addr)))) { perror("ClientBindFailed:"); exit(1); } //声明一个服务器端的socket地址结构,并用服务器那边的IP地址及端口对其进行初始化,用于后面的连接 structsockaddr_inserver_addr; bzero(&server_addr,sizeof(server_addr)); server_addr.sin_family=AF_INET; if(inet_pton(AF_INET,"127.0.0.1",&server_addr.sin_addr)==0) { perror("ServerIPAddressError:"); exit(1); } server_addr.sin_port=htons(SERVER_PORT); socklen_tserver_addr_length=sizeof(server_addr); //向服务器发起连接,连接成功后client_socket_fd代表了客户端和服务器的一个socket连接 if(connect(client_socket_fd,(structsockaddr*)&server_addr,server_addr_length)<0) { perror("CanNotConnectToServerIP:"); exit(0); } //输入文件名并放到缓冲区buffer中等待发送 charfile_name[FILE_NAME_MAX_SIZE+1]; bzero(file_name,FILE_NAME_MAX_SIZE+1); printf("PleaseInputFileNameOnServer:\t"); scanf("%s",file_name); charbuffer[BUFFER_SIZE]; bzero(buffer,BUFFER_SIZE); strncpy(buffer,file_name,strlen(file_name)>BUFFER_SIZE?BUFFER_SIZE:strlen(file_name)); //向服务器发送buffer中的数据 if(send(client_socket_fd,buffer,BUFFER_SIZE,0)<0) { perror("SendFileNameFailed:"); exit(1); } //打开文件,准备写入 FILE*fp=fopen(file_name,"w"); if(NULL==fp) { printf("File:\t%sCanNotOpenToWrite\n",file_name); exit(1); } //从服务器接收数据到buffer中 //每接收一段数据,便将其写入文件中,循环直到文件接收完并写完为止 bzero(buffer,BUFFER_SIZE); intlength=0; while((length=recv(client_socket_fd,buffer,BUFFER_SIZE,0))>0) { if(fwrite(buffer,sizeof(char),length,fp)<length) { printf("File:\t%sWriteFailed\n",file_name); break; } bzero(buffer,BUFFER_SIZE); } //接收成功后,关闭文件,关闭socket printf("ReceiveFile:\t%sFromServerIPSuccessful!\n",file_name); close(fp); close(client_socket_fd); return0; }
该程序备有较为详尽的注释,相信不难理解。感兴趣的朋友可以在此基础上尝试一些功能的扩展,使其功能更加强大。