zl程序教程

您现在的位置是:首页 >  系统

当前栏目

Linux网络编程之socket文件传输示例

Linux网络编程 示例 socket 文件传输
2023-06-13 09:15:42 时间

本文所述示例程序是基于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;
}

该程序备有较为详尽的注释,相信不难理解。感兴趣的朋友可以在此基础上尝试一些功能的扩展,使其功能更加强大。