server
#include<stdio.h>
#include<sys/types.h>
#include<sys/socket.h>
#include<stdlib.h>
#include<netinet/in.h>
#include<arpa/inet.h>
#include<pthread.h>
#define FILE_NAME_MAX_SIZE 512
char buf[1024];//缓冲区
int ad[10];//最大连接数
const int port = 8085;
const char* ip="172.16.10.207";
void *thread_fun1(void *arg)
{
//while(1)
// {
// memset(buf, '\0', sizeof(buf));//清空buf
// ssize_t _s=read(ad[(int)arg],buf,sizeof(buf)-1);
// if(_s>0)
// {
// buf[_s]=0;
// printf("client# %s\n",buf);
// }
// else
// {
// printf("client is quit!\n");
// break;
// }
// write(ad[(int)arg],buf,strlen(buf));
// }
// return NULL;
while(1)
{
if (recv(ad[(int)arg], buf, 1024, 0) < 0)
{
printf("Server Recieve Data Failed:");
break;
}
// 然后从buffer(缓冲区)拷贝到file_name中
char file_name[FILE_NAME_MAX_SIZE + 1];
bzero(file_name, FILE_NAME_MAX_SIZE + 1);
strncpy(file_name, buf, strlen(buf)>FILE_NAME_MAX_SIZE ? FILE_NAME_MAX_SIZE : strlen(buf));
printf("%s\n", file_name);
// 打开文件并读取文件数据
FILE *fp = fopen(file_name, "r");
if (NULL == fp)
{
printf("File:%s Not Found\n", file_name);
}
else
{
bzero(buf,1024);
int length = 0;
// 每读取一段数据,便将其发送给客户端,循环直到文件读完为止
while ((length = fread(buf, sizeof(char), 1024, fp)) > 0)
{
if (send(ad[(int)arg], buf, length, 0) < 0)
{
printf("Send File:%s Failed./n", file_name);
break;
}
bzero(buf, 1024);
}
// 关闭文件
fclose(fp);
printf("File:%s Transfer Successful!\n", file_name);
}
// 关闭与客户端的连接
close(ad[(int)arg]);
}
}
// void *thread_fun2(void *arg)
// {
// while(1)
// {
// memset(buf, '\0', sizeof(buf));//清空buf
// ssize_t _s=write(ad[(int)arg],buf,strlen(buf));
// if(_s>0)
// {
// buf[_s]=0;
// printf("client# %s\n",buf);
// }
// else
// {
// printf("client is quit!\n");
// break;
// }
// }
// return NULL;
// }
int main(int argc,char* argv[])
{
int sock=socket(AF_INET,SOCK_STREAM,0);//打开一个网络通信窗口
if(sock<0)
{
perror("socket");
exit(1);
}
struct sockaddr_in local;//服务端
local.sin_family=AF_INET; //地址族
local.sin_port=htons(port);//16位TCP/UDP端口号
//local.sin_addr.s_addr=inet_addr(ip);//32位IP地址
local.sin_addr.s_addr=htonl(INADDR_ANY);
socklen_t len=sizeof(local);
if(bind(sock,(struct sockaddr*)&local,len)<0)//绑定一个固定的网络地址和端口号
{
perror("bind");
exit(2);
}
if(listen(sock,5)<0)//导致套接口从closed状态换到listen状态
{
perror("listen");
exit(3);
}
pthread_t tid[10];
int err;
int i=0;
//socklen_t len=sizeof(struct sockaddr_in);
while(1)
{
struct sockaddr_in remote;//用于客户端的socket定义和赋值
socklen_t remote_len = sizeof(remote);
ad[i]=accept(sock,(struct sockaddr*)&remote,&remote_len);
if(ad[i]<0)
{
perror("accept");
continue;
}
printf("client,ip:%s,port:%d\n",inet_ntoa(remote.sin_addr)\
,ntohs(remote.sin_port));
err=pthread_create(&tid[i],NULL,thread_fun1,(void *)i);
//err=pthread_create(&tid[i],NULL,thread_fun2,(void *)i);
if(err !=0)
{
printf("create new thread failed\n");
close(ad[i]);
}
i++;
}
close(sock);
return 0;
}
client
#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
#define SERVER_PORT 8085
#define BUFFER_SIZE 1024
#define FILE_NAME_MAX_SIZE 512
int main()
{
// 声明并初始化一个客户端的socket地址结构
struct sockaddr_in client_addr;
//设置client_addr前size个字节为0
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描述符
int client_socket_fd = socket(AF_INET, SOCK_STREAM, 0);
if (client_socket_fd < 0)
{
perror("Create Socket Failed:");
exit(1);
}
// 绑定客户端的socket和客户端的socket地址结构 非必需
if (-1 == (bind(client_socket_fd, (struct sockaddr*)&client_addr, sizeof(client_addr))))
{
perror("Client Bind Failed:");
exit(1);
}
// 声明一个服务器端的socket地址结构,并用服务器那边的IP地址及端口对其进行初始化,用于后面的连接
struct sockaddr_in server_addr;
bzero(&server_addr, sizeof(server_addr));
server_addr.sin_family = AF_INET;
//将IP地址从字符串格式转换成网络地址格式
if (inet_pton(AF_INET, "172.16.10.207", &server_addr.sin_addr) == 0)
{
perror("Server IP Address Error:");
exit(1);
}
server_addr.sin_port = htons(SERVER_PORT);//将主机字节顺序转换为网络字节顺序
//和int有点像用来表示长度
socklen_t server_addr_length = sizeof(server_addr);
// 向服务器发起连接,连接成功后client_socket_fd代表了客户端和服务器的一个socket连接
if (connect(client_socket_fd, (struct sockaddr*)&server_addr, server_addr_length) < 0)
{
perror("Can Not Connect To Server IP:");
exit(0);
}
// 输入文件名 并放到缓冲区buffer中等待发送
char file_name[FILE_NAME_MAX_SIZE + 1];
char file_name_save[FILE_NAME_MAX_SIZE + 1];
bzero(file_name, FILE_NAME_MAX_SIZE + 1);
printf("Please Input File Name On Server:\t");
// scanf()函数返回成功赋值的数据项数,读到文件末尾出错时则返回EOF
scanf("%s", file_name);
char buffer[BUFFER_SIZE];
bzero(buffer, BUFFER_SIZE);
//把file_name所指由NULL结束的字符串的前n个字节复制到buffer所指的数组中。
strncpy(buffer, file_name, strlen(file_name)>BUFFER_SIZE ? BUFFER_SIZE : strlen(file_name));
// 向client_socket_fd发送buffer中的数据
if (send(client_socket_fd, buffer, BUFFER_SIZE, 0) < 0)
{
perror("Send File Name Failed:");
exit(1);
}
//输入要保存的地址
printf("Please Input File Name to Save:\t");
scanf("%s", file_name_save);
// 打开文件,准备写入
FILE *fp = fopen(file_name_save, "w");
if (NULL == fp)
{
printf("File:\t%s Can Not Open To Write\n", file_name_save);
exit(1);
}
// 从服务器接收数据到buffer中
// 每接收一段数据,便将其写入文件中,循环直到文件接收完并写完为止
bzero(buffer, BUFFER_SIZE);
int length = 0;
//不论是客户还是服务器应用程序都用recv函数从TCP连接的另一端接收数据
//用buffer来存放recv函数接收到的数据
while ((length = recv(client_socket_fd, buffer, BUFFER_SIZE, 0)) > 0)
{
//buffer所指的内容输出到fp这个文件中,
if (fwrite(buffer, sizeof(char), length, fp) < length)
{
printf("File:\t%s Write Failed\n", file_name);
break;
}
bzero(buffer, BUFFER_SIZE);
}
// 接收成功后,关闭文件,关闭socket
printf("Receive File:\t%s From Server IP Successful!\n", file_name);
close(fp);
close(client_socket_fd);
return 0;
}