一、实验目的
在上次循环面向连接的程序的基础上,利用TCP完成linux和windows平台的文件传输。
二、实验要求
实现程序的调通运行并理解windows上的socket编程和linux的不同。
Windows下的客户端代码
#pragma comment(lib,"wsock32.lib")
#include <windows.h>
#include<string.h>
#include <stdio.h>
#include <stdlib.h>
#include <winsock2.h>
#include <stdlib.h> //for malloc
#define PORT 6666
#define MaxLen 1024
typedef struct sockaddr_in addr;
int Initsocket(void);
int Initsocket(void)
{
WSADATA wsadata;
WORD version;
int err;
version = MAKEWORD(2,2);
err = WSAStartup(version,&wsadata);
if(err)
{
printf("Error %d:winsock not available\n");
return 1;
}
return 0;
}
void send_file(int sockcd)
{
char filepath[100];
FILE *fp;
int lenpath; //filepath length
char *buffer;//file buffer
int fileTrans;
buffer = (char *)malloc(sizeof(char)*MaxLen);
memset(buffer,0,MaxLen);
printf("file path:\n");
scanf("%s",filepath);//get filepath
printf("filepath : %s\n",filepath);
lenpath = send(sockcd,filepath,strlen(filepath),0);// put file path to sever
if(lenpath<0)
{
printf("filepath send error!\n");
}
else
{
printf("filepath send success!\n");
}
//sleep(3);
fp = fopen(filepath,"r");//opne file
if(fp==NULL)
{
printf("filepath not found!\n");
exit(1);
}
while((fileTrans = fread(buffer,sizeof(char),MaxLen,fp))>0)
{
//printf("fileTrans =%d\n",fileTrans);
if(send(sockcd,buffer,fileTrans,0)<0)
{
printf("send failed!\n");
break;
}
memset(buffer,0,MaxLen);
//memset(buffer,0,sizeof(buffer));
}
fclose(fp);
}
int main()
{
SOCKET client;
int err;
char bufferw[MaxLen];
char bufferr[MaxLen];
addr server_add;
int i;
Initsocket();
if((client = socket(PF_INET,SOCK_STREAM,0)) == INVALID_SOCKET)
{
printf("no more socket resource\n");
return 1;
}
// 服务器地址初始化
server_add.sin_family = PF_INET;
server_add.sin_port = htons(PORT);
server_add.sin_addr.S_un.S_addr = inet_addr("192.168.225.133");
if((err = connect(client,(struct sockaddr*)&server_add,sizeof(addr))) == INVALID_SOCKET)
{
printf("error %d:cannot connect to server\n");
return 1;
}
else
{
printf("link server is successful\n");
send_file(client);
}
closesocket(client);
WSACleanup();
return 0;
}
linux下服务器代码
#include <stdio.h>
#include <sys/socket.h>
#include <sys/types.h>
#include <string.h>
#include <netinet/in.h>
#include <errno.h>
#include <memory.h>
#include <stdlib.h> //for malloc
#include<arpa/inet.h>
#define MAXLINE 4096
#define BUFFER_SIZE 1024
void recvfilename(int temp)
{
char filename[100];
char filepath[100];
memset(filename,'\0',sizeof(filename));
memset(filepath,'\0',sizeof(filepath));
char *buffer;//file buffer
buffer = (char *)malloc(sizeof(char)*BUFFER_SIZE);
bzero(buffer,BUFFER_SIZE);
int lenfilepath;
int fileTrans;
lenfilepath = recv(temp,filepath,100,0);
printf("filepath :%s\n",filepath);
FILE *fp;
int writelength;
if(lenfilepath<0)
{
printf("recv error!\n");
}
//从路径中提取出文件名
else
{
int i=0,k=0;
for(i=strlen(filepath); i>=0; i--)
{
if(filepath[i]!='/')
{
k++;
}
else
break;
}
strcpy(filename,filepath+(strlen(filepath)-k)+1);
}
printf("filename :%s\n",filename);
//以写的方式打开文件
fp = fopen(filename,"w");
if(fp!=NULL)
{
//接受文件内容buffer,存在buffer中
while(fileTrans =recv(temp,buffer,BUFFER_SIZE,0))
{
if(fileTrans<0)
{
printf("recv error!\n");
break;
}
//把buffter中的文件内容写到fp指针指的文件中
writelength = fwrite(buffer,sizeof(char),fileTrans,fp);
if(writelength <fileTrans)
{
printf("write error!\n");
break;
}
bzero(buffer,BUFFER_SIZE);
//memset(buffer,0,sizeof(buffer));
}
printf("recv finished!\n");
fclose(fp);
}
}
int main()
{
int temp;//accept
struct sockaddr_in client;
socklen_t addrlen;
int sockfd;
//创建套接字
sockfd = passiveTCP("6666", 10);
addrlen = sizeof(client);
while(1)
{
temp = accept(sockfd,(struct sockaddr*)&client,&addrlen);
if(temp <= 0)
{
printf("accept error!\n");
close(temp);
}
else
{
printf("client IP: %s\n",inet_ntoa(client.sin_addr));
}
//接受文件路径,返回文件路径的长度
recvfilename(temp);
}
return 0;
}
实验现象
在windows下写了个aa.txt文本内容是hello
运行windows下客户端代码 输入相对路径下的aa.txt文本文件 发现发送成功
在linux下服务器
同时可以看到服务器代码所在文件下收到了文件。