简介
通过tcp连接实现客户端上传,服务器端下载功能,需要注意字符串的解析以及粘包问题
客户端
头文件
#ifndef _MIAN_H_
#define _MIAN_H_
#include <stdio.h>
#include <stdlib.h>
#include <string.h>
#include <unistd.h>
#include <arpa/inet.h>
#include <sys/socket.h>
#include <netinet/in.h>
#include <netinet/ip.h>
#include <sys/types.h>
#include <sys/stat.h>
#include <fcntl.h>
int parseStr(char *str,char *cmd,char *filename);
int do_work(int sockfd,char *cmd,char *filename);
int upload(int sockfd,char *filename);
#endif
客户端通过tcp连接到服务器端
#include "./main.h"
int tcp_connect(const char *ip,int port)
{
int tcp_socket = socket(AF_INET,SOCK_STREAM,0);
if(tcp_socket < 0)
{
perror("socket error");
return -1;
}
printf("socket ok!\n");
struct sockaddr_in server;
server.sin_family = AF_INET;
server.sin_port = htons(port);
server.sin_addr.s_addr = inet_addr(ip);
if(connect(tcp_socket,(struct sockaddr*)&server,sizeof(server)) < 0)
{
perror("connect error");
return -1;
}
return tcp_socket;
}
int tcp_com(int sockfd)
{
char buf[100] = {'\0'};
char cmd[50] = {'\0'};
char filename[50] = {'\0'};
printf("input cmd filename:");
while(1)
{
fgets(buf,sizeof(buf),stdin);
send(sockfd,buf,strlen(buf),0);
if(strncasecmp(buf,"quit",4) == 0) return -1;
parseStr(buf,cmd,filename);
printf("cmd is %s\nfilename is %s\n",cmd,filename);
do_work(sockfd,cmd,filename);
memset(buf,'\0',sizeof(buf));
}
}
int main(int argc, const char *argv[])
{
if(argc < 3)
{
perror("input ./app ip port");
return -1;
}
int sockfd = tcp_connect(argv[1],atoi(argv[2]));
int flag = tcp_com(sockfd);
if(flag < 0)
{
close(sockfd);
}
return 0;
}
字符串解析函数
#include "./main.h"
int parseStr(char *str,char *cmd,char *filename);
int parseStr(char *str,char *cmd,char *filename)
{
if(NULL == str || NULL == cmd || NULL == filename)
{
perror("NULL error");
return -1;
}
while(*str != '#')
{
if(*str == ' ') break;
*cmd = *str;
str++;
cmd++;
}
*cmd = '\0';
str++;
while(*str!='#')
{
*filename = *str;
str++;
filename++;
}
*filename = '\0';
return 0;
}
上传函数
#include "./main.h"
int do_work(int sockfd,char *cmd,char *filename);
int upload(int sockfd,char *filename);
int upload(int sockfd,char *filename)
{
struct stat myFile;
if(stat(filename,&myFile) < 0)
{
perror("stat error");
return -1;
}
int fileSize = myFile.st_size;
printf("fileSize = %d\n",fileSize);
sleep(3);
send(sockfd,&fileSize,sizeof(fileSize),0);
int fd = open(filename,O_RDONLY);
char buf[100] = {'\0'};
int ret = 0;
printf("发送数据中。。。\n");
while(1)
{
ret = read(fd,buf,sizeof(buf));
if(0 == ret)
{
break;
}
send(sockfd,buf,ret,0);
memset(buf,'\0',sizeof(buf));
}
printf("发送完毕\n");
close(fd);
return 0;
}
int do_work(int sockfd,char *cmd,char *filename)
{
if(strncmp(cmd,"put",3) == 0)
{
printf("上传文件\n");
upload(sockfd,filename);
}else if(strncmp(cmd,"get",3) == 0)
{
}
return 0;
}
服务器端
头文件
#ifndef _MIAN_H_
#define _MIAN_H_
#include <stdio.h>
#include <stdlib.h>
#include <string.h>
#include <unistd.h>
#include <arpa/inet.h>
#include <sys/socket.h>
#include <netinet/in.h>
#include <netinet/ip.h>
#include <sys/types.h>
#include <sys/stat.h>
#include <sys/fcntl.h>
int parseStr(char *str,char *cmd,char *filename);
int do_work(int newfd,char *cmd,char *filename);
int down_load(int newfd,char *filename);
#endif
服务器端建立tcp连接
#include "./main.h"
int tcp_server(const char *ip,int port)
{
int tcp_socket = socket(AF_INET,SOCK_STREAM,0);
if(tcp_socket < 0)
{
perror("socket error");
return -1;
}
printf("socket ok!\n");
struct sockaddr_in MyAddr;
memset(&MyAddr,'\0',sizeof(MyAddr));
MyAddr.sin_family = AF_INET;
MyAddr.sin_port = htons(port);
MyAddr.sin_addr.s_addr = inet_addr(ip);
if(bind(tcp_socket,(struct sockaddr *)&MyAddr,sizeof(MyAddr)) < 0)
{
perror("bind error");
return -1;
}
printf("bind ok!\n");
if(listen(tcp_socket,5) < 0)
{
perror("listen error");
return -1;
}
printf("listen ok!\n");
return tcp_socket;
}
int tcp_com(int newfd)
{
char buf[100] = {'\0'};
char cmd[50] = {'\0'};
char filename[50] = {'\0'};
while(1)
{
memset(buf,'\0',sizeof(buf));
recv(newfd,buf,sizeof(buf),0);
if(strncasecmp(buf,"quit",4) == 0)
{
return -1;
}
parseStr(buf,cmd,filename);
printf("cmd is %s\nfilename is %s\n",cmd,filename);
do_work(newfd,cmd,filename);
}
}
int main(int argc, const char *argv[])
{
if(argc < 3)
{
printf("input add ip port\n");
return -1;
}
int listenfd = tcp_server(argv[1],atoi(argv[2]));
struct sockaddr_in client;
memset(&client,'\0',sizeof(client));
int len = sizeof(client);
int newfd = accept(listenfd,(struct sockaddr *)&client,&len);
if(newfd < 0)
{
perror("accept error");
return -1;
}
printf("client ip is %s port is %d\n",inet_ntoa(client.sin_addr),ntohs(client.sin_port));
int n = tcp_com(newfd);
if(n < 0)
{
close(newfd);
}
close(listenfd);
return 0;
}
字符串解析函数
#include "./main.h"
int parseStr(char *str,char *cmd,char *filename);
int parseStr(char *str,char *cmd,char *filename)
{
if(NULL == str || NULL == cmd || NULL == filename)
{
perror("NULL error");
return -1;
}
while(*str != '#')
{
if(*str == ' ') break;
*cmd = *str;
str++;
cmd++;
}
*cmd = '\0';
str++;
while(*str!='#')
{
*filename = *str;
str++;
filename++;
}
*filename = '\0';
return 0;
}
服务器端下载
#include "./main.h"
int do_work(int newfd,char *cmd,char *filename);
int down_load(int newfd,char *filename);
int down_load(int newfd,char *filename)
{
int fileSize = 0;
recv(newfd,&fileSize,sizeof(fileSize),0);
printf("fileSize = %d\n",fileSize);
char buf[100] = {'\0'};
int fd = open(filename,O_WRONLY|O_CREAT|O_TRUNC,0777);
int count = 0;
int ret = 0;
printf("接收数据中。。。\n");
while(count < fileSize)
{
ret = recv(newfd,buf,sizeof(buf),0);
write(fd,buf,ret);
count += ret;
memset(buf,'\0',sizeof(buf));
}
printf("接收数据成功\n");
close(fd);
return 0;
}
int do_work(int newfd,char *cmd,char *filename)
{
if(strncmp(cmd,"puts",3) == 0)
{
printf("开始下载文件\n");
down_load(newfd,filename);
}
else if(strncmp(cmd,"gets",3) == 0)
{
}
return 0;
}