一、客户端代码
客户端代码
cs
//实现TCP客户端通信
#include<stdio.h>
#include<unistd.h>
#include<sys/stat.h>
#include<sys/types.h>
#include<sys/socket.h>
#include<string.h>
#include<netinet/ip.h>
#include<netinet/in.h>
#include<arpa/inet.h>
#include<fcntl.h>
int main(int argc, const char *argv[])
{
//1、创建套接字
int sockfd=socket(AF_INET,SOCK_STREAM,0);
if(sockfd<0)
{
printf("创建失败\n");
return -1;
}
/*
//2、绑定套接字
//填写自己的地址信息,不是必要的
struct sockaddr_in clientaddr;
clientaddr.sin_family=AF_INET;
clientaddr.sin_port=htons(10000);
clientaddr.sin_addr.s_addr=inet_addr("192.168.124.29");
int bind_ret=bind(sockfd,(struct sockaddr *)&clientaddr,sizeof(clientaddr));
if(bind_ret<0)
{
printf("绑定失败\n");
return -1;
}*/
//3、建立连接connect
//填写对方信息
struct sockaddr_in destaddr;
destaddr.sin_family=AF_INET;
destaddr.sin_port=htons(8888);
destaddr.sin_addr.s_addr=inet_addr("192.168.124.29");
int connect_ret=connect(sockfd,(struct sockaddr*)&destaddr,sizeof(destaddr));
if(connect_ret<0)
{
printf("连接失败\n");
return -1;
}
//4、发送数据send
while(1)
{
char buf[100];
scanf("%s",buf);
send(sockfd,buf,100,0);
int fd=open(buf,O_WRONLY|O_CREAT|O_TRUNC,0664);
if(fd<0)
{
printf("open failed");
return -1;
}
while(1)
{
bzero(buf,100);
int ret=recv(sockfd,buf,100,0);
printf("%s",buf);
if(ret==0)
break;
write(fd,buf,ret);
}
}
//6、关闭文件
close(sockfd);
return 0;
}
二、服务器代码
服务器使用IO多路复用
cs
#include <stdio.h>
#include <unistd.h>
#include <sys/stat.h>
#include <stdlib.h>
#include <netinet/in.h>
#include <netinet/ip.h>
#include <arpa/inet.h>
#include <sys/types.h>
#include <sys/socket.h>
#include <string.h>
#include<fcntl.h>
#define SERVERADDR "192.168.124.29"
#define PORT 8888
int main(int argc, const char *argv[]) {
// 创建套接字
int listenfd = socket(AF_INET, SOCK_STREAM, 0);
if (listenfd < 0) {
perror("socket failed");
return -1;
}
// 绑定套接字
struct sockaddr_in serveraddr;
serveraddr.sin_family = AF_INET;
serveraddr.sin_port = htons(PORT);
serveraddr.sin_addr.s_addr = inet_addr(SERVERADDR);
if (bind(listenfd, (struct sockaddr*)&serveraddr, sizeof(serveraddr)) < 0) {
perror("bind failed");
return -1;
}
// 监听套接字
if (listen(listenfd, 20) < 0) {
perror("listen failed");
return -1;
}
//定义文件描述符表
fd_set master_fds, read_fds;
int max_fd = listenfd;
//清空文件描述符表
FD_ZERO(&master_fds);
//将监听套接字加入文件描述符表
FD_SET(listenfd, &master_fds);
while (1)
{
read_fds = master_fds;
// 监视文件描述符集,进程通知内核监视的内核是否准备就绪(是否有IO事件)
int activity = select(max_fd + 1, &read_fds, NULL, NULL, NULL);
if (activity < 0)
{
perror("select failed");
return -1;
}
// 处理新连接
if (FD_ISSET(listenfd, &read_fds))
{
struct sockaddr_in clientaddr;
socklen_t len = sizeof(clientaddr);
int client_fd = accept(listenfd, (struct sockaddr*)&clientaddr, &len);
if (client_fd < 0)
{
perror("accept failed");
continue;
}
printf("New connection from %s:%hu\n", inet_ntoa(clientaddr.sin_addr), ntohs(clientaddr.sin_port));
//将新创建的客户端文件描述符加入到文件描述符表当中
FD_SET(client_fd, &master_fds);
if (client_fd > max_fd)
{
max_fd = client_fd;
}
}
// 处理已连接客户端的数据
for (int i = listenfd + 1; i <= max_fd; ++i)
{
if (FD_ISSET(i, &read_fds))
{
char buf[100];
bzero(buf, 100);
int ret = read(i, buf, 100);
int fd=open(buf,O_RDONLY);
if(fd<0)
{
printf("open failed\n");
return -1;
}
char file[100];
while(1)
{
bzero(file,100);
int read_ret = read(fd,file,100);
printf("%d ",read_ret);
if(read_ret==0)
break;
send(i, file, read_ret,0);
}
printf("download ok\n");
}
}
}
close(listenfd);
return 0;
}