流式域服务器
#include <myhd.h>
#define PORT 8888 //端口号
#define IP "192.168.114.13" //IP地址
int main(int argc, const char *argv[])
{
//1、创建用于接受链接的套接字
int sfd=socket(AF_UNIX,SOCK_STREAM,0);
if(sfd==-1)
{
perror("socket error");
return -1;
}
printf("socket success sfd=%d\n",sfd);
//设置端口号快速重用
int reuse=1;
if(setsockopt(sfd,SOL_SOCKET,SO_REUSEADDR,&reuse,sizeof(reuse))==-1)
{
perror("setsockopt error");
return -1;
}
printf("设置端口快速重用成功\n");
//判断套接字文件是否存在
if(access("mySock",F_OK)==0)
{
if(unlink("./mySock")!=0)
{
perror("unlink error");
return -1;
}
}
//2、绑定IP地址和端口号
//2.1、填充要绑定的地址信息结构体
struct sockaddr_un sun;
sun.sun_family=AF_UNIX;
strcpy(sun.sun_path,"mySock");
//2.2、绑定
if(bind(sfd,(struct sockaddr*)&sun,sizeof(sun))==-1)
{
perror("bind error");
return -1;
}
printf("bing success _%d_%s_%s_\n",__LINE__,__FILE__,__func__);
//3、将套接字设置成被动监听状态
if(listen(sfd,128)==-1)
{
perror("listen error");
return -1;
}
printf("listen success _%d_%s_%s_\n",__LINE__,__FILE__,__func__);
//4、阻塞等待客户端链接请求,如果有新的客户端连接,则创建一个新的用于通信的套接字
//4.1、定义客户端地址信息结构体
struct sockaddr_un cun; //客户端地址信息结构体
cun.sun_family=AF_UNIX;
socklen_t socklen=sizeof(cun); //客户端地址信息大小
//4.2、阻塞接收客户端的连接请求,并且获取客户端的地址信息
int newfd=accept(sfd,(struct sockaddr*)&cun,&socklen);
if(newfd==-1)
{
perror("accept error");
return -1;
}
printf("accept success _%d_%s_%s_\n",__LINE__,__FILE__,__func__);
//5、收发数据使用newfd完成通信
char buf[128]="";
while(1)
{
//清空字符串
bzero(buf,sizeof(buf));
//read(newfd,buf,sizeof(buf)); //从套接字中读取客户端发来的消息
int res=recv(newfd,buf,sizeof(buf),0);
//判断收到的结果
if(res==0)
{
printf("客户端已经下线\n");
break;
}
else if(res<0)
{
perror("recv error");
return -1;
}
printf("[%s]:%s\n",cun.sun_path,buf);
//将读取的信息加上一些字符发送回去
strcat(buf,"*_*");
//write(newfd,buf,sizeof(buf));
send(newfd,buf,sizeof(buf),0);
printf("发送成功\n");
}
//6、关闭所有套接字
close(sfd);
close(newfd);
return 0;
}
流式域客户端
#include <myhd.h>
int main(int argc, const char *argv[])
{
//1、创建客户端用于通信的套接字
int cfd=socket(AF_UNIX,SOCK_STREAM,0);
if(cfd==-1)
{
perror("socket error");
return -1;
}
printf("cfd=%d\n",cfd);
//判断套接字文件是否存在
if(access("cliSock",F_OK)==0)
{
if(unlink("./cliSock")!=0)
{
perror("unlink error");
return -1;
}
}
//2、绑定
//2.1、填充地址信息结构体
struct sockaddr_un cun;
cun.sun_family=AF_UNIX;
strcpy(cun.sun_path,"cliSock");
//2.2、绑定工作
if(bind(cfd,(struct sockaddr*)&cun,sizeof(cun))==-1)
{
perror("bind error");
return -1;
}
printf("bind success\n");
//3、连接服务器
//3.1、填充服务器地址信息结构体
struct sockaddr_un sun;
sun.sun_family=AF_UNIX; //使用ipv4通信
strcpy(sun.sun_path,"mySock");
//3.2、连接服务器
if(connect(cfd,(struct sockaddr*)&sun,sizeof(sun))==-1)
{
perror("connect error");
return -1;
}
printf("connect success\n");
//4、收发数据
char buf[128]="";
char rbuf[128]="";
while(1)
{
bzero(buf,sizeof(buf));
bzero(rbuf,sizeof(rbuf));
printf("请输入:");
fgets(buf,sizeof(buf),stdin); //从标准输入中读取数据
buf[strlen(buf)-1]='\0';
//将数据发送给服务器
send(cfd,buf,sizeof(buf),0);
//输入quit退出
if(strcmp(buf,"quit")==0)
{
break;
}
//接收服务器发送来的消息
int res=recv(cfd,rbuf,sizeof(rbuf),0);
if(res==0)
{
printf("服务器已经关闭\n");
break;
}
printf("rbuf=%s\n",rbuf);
}
//5、关闭客户端套接字文件
close(cfd);
return 0;
}
报式域服务器
#include <myhd.h>
int main(int argc, const char *argv[])
{
//1、创建用于接受链接的套接字
int sfd=socket(AF_UNIX,SOCK_DGRAM,0);
if(sfd==-1)
{
perror("socket error");
return -1;
}
printf("socket success sfd=%d\n",sfd);
//设置端口号快速重用
int reuse=1;
if(setsockopt(sfd,SOL_SOCKET,SO_REUSEADDR,&reuse,sizeof(reuse))==-1)
{
perror("setsockopt error");
return -1;
}
printf("设置端口快速重用成功\n");
//判断套接字文件是否存在
if(access("mySock",F_OK)==0)
{
if(unlink("./mySock")!=0)
{
perror("unlink error");
return -1;
}
}
//2、绑定IP地址和端口号
//2.1、填充要绑定的地址信息结构体
struct sockaddr_un sun;
sun.sun_family=AF_UNIX;
strcpy(sun.sun_path,"mySock");
//2.2、绑定
if(bind(sfd,(struct sockaddr*)&sun,sizeof(sun))==-1)
{
perror("bind error");
return -1;
}
printf("bing success _%d_%s_%s_\n",__LINE__,__FILE__,__func__);
//4、阻塞等待客户端链接请求,如果有新的客户端连接,则创建一个新的用于通信的套接字
//4.1、定义客户端地址信息结构体
struct sockaddr_un cun; //客户端地址信息结构体
cun.sun_family=AF_UNIX;
socklen_t socklen=sizeof(cun); //客户端地址信息大小
//5、收发数据使用newfd完成通信
char buf[128]="";
while(1)
{
//清空字符串
bzero(buf,sizeof(buf));
//read(newfd,buf,sizeof(buf)); //从套接字中读取客户端发来的消息
int res=recvfrom(sfd,buf,sizeof(buf),0,(struct sockaddr*)&cun,&socklen);
//判断收到的结果
if(res==0)
{
printf("客户端已经下线\n");
break;
}
else if(res<0)
{
perror("recv error");
return -1;
}
printf("[%s]:%s\n",cun.sun_path,buf);
//将读取的信息加上一些字符发送回去
strcat(buf,"*_*");
//write(newfd,buf,sizeof(buf));
sendto(sfd,buf,sizeof(buf),0,(struct sockaddr*)&cun,sizeof(cun));
printf("发送成功\n");
}
//6、关闭所有套接字
close(sfd);
return 0;
}
报式域客户端
#include <myhd.h>
int main(int argc, const char *argv[])
{
//1、创建客户端用于通信的套接字
int cfd=socket(AF_UNIX,SOCK_DGRAM,0);
if(cfd==-1)
{
perror("socket error");
return -1;
}
printf("cfd=%d\n",cfd);
//判断套接字文件是否存在
if(access("cliSock",F_OK)==0)
{
if(unlink("./cliSock")!=0)
{
perror("unlink error");
return -1;
}
}
//2、绑定
//2.1、填充地址信息结构体
struct sockaddr_un sun;
sun.sun_family=AF_UNIX;
strcpy(sun.sun_path,"cliSock");
//2.2、绑定工作
if(bind(cfd,(struct sockaddr*)&sun,sizeof(sun))==-1)
{
perror("bind error");
return -1;
}
printf("bind success\n");
struct sockaddr_un cun;
cun.sun_family=AF_UNIX;
strcpy(cun.sun_path,"mySock");
//4、收发数据
char buf[128]="";
char rbuf[128]="";
while(1)
{
bzero(buf,sizeof(buf));
bzero(rbuf,sizeof(rbuf));
printf("请输入:");
fgets(buf,sizeof(buf),stdin); //从标准输入中读取数据
buf[strlen(buf)-1]='\0';
//将数据发送给服务器
sendto(cfd,buf,sizeof(buf),0,(struct sockaddr*)&cun,sizeof(cun));
//输入quit退出
if(strcmp(buf,"quit")==0)
{
break;
}
//接收服务器发送来的消息
int res=recvfrom(cfd,rbuf,sizeof(rbuf),0,NULL,NULL);
if(res==0)
{
printf("服务器已经关闭\n");
break;
}
printf("rbuf=%s\n",rbuf);
}
//5、关闭客户端套接字文件
close(cfd);
return 0;
}
tftp
#include <myhd.h>
//实现下载功能
int Do_download(int cfd,struct sockaddr_in sin)
{
socklen_t socklen=sizeof(sin);
//定义变量存储下载请求包
char buf[516]="";
//定义变量存储文件名
char fileName[40]="";
printf("请输入文件名:");
scanf("%s",fileName);
getchar();
//组装请求包
short *p1=(short*)buf;
*p1=htons(1); //1下载/2上传
char *p2=buf+2; //文件名段
strcpy(p2,fileName);
//printf("strlen(p2)=%lx\n",strlen(p2));
char *p4=p2+strlen(p2)+1; //模式段
strcpy(p4,"octet");
int size=4+strlen(p2)+strlen(p4); //要发送数据的大小
//向服务器发送下载请求
if(sendto(cfd,buf,size,0,(struct sockaddr*)&sin,sizeof(sin))==-1)
{
perror("sendto error");
return -1;
}
printf("请求成功\n");
int wfd;
if((wfd=open("./text1.txt",O_RDWR|O_APPEND|O_CREAT,0664))==-1)
{
perror("open error");
return -1;
}
//循环接收回复服务器发来的消息
while(1)
{
//接收数据包
bzero(buf,sizeof(buf));
if(recvfrom(cfd,buf,size,0,(struct sockaddr*)&sin,&socklen)==-1)
{
perror("recvfrom error");
return -1;
}
//拆分数据包
//操作码段
short *q1=(short *)buf;
//得到块编号
short *q2=q1+2; //*q2为块编号
//数据段为0则下载完成退出循环
char *q3=buf+4;
//char q3[512]="";
//int i=4;
//int j=0;
//while(buf[i]!='\0'||i<=516)
//{
// q3[j]=buf[i];
// i++;j++;
//}
if(strlen(q3)<=0)
{
break;
}
printf("strlen(q3)=%lx\n",strlen(q3));
write(wfd,q3,strlen(q3));
//向服务器发送ACK
bzero(buf,sizeof(buf));
//ACK组装
short *j1=(short *)buf;
*j1=htons(4); //ACK
//块编号段
short *j2=(short *)buf+2;
*j2=*q2;
//向服务器发送ACK
if(sendto(cfd,buf,4,0,(struct sockaddr*)&sin,sizeof(sin))==-1)
{
perror("ACK sendto error");
return -1;
}
printf("ACK返回成功\n");
}
}
int Do_upload(int cfd,struct sockaddr_in sin)
{
socklen_t socklen=sizeof(sin);
//定义变量存储上传请求包
char buf[516]="";
//定义变量存储文件名
char fileName[40]="";
printf("请输入文件名:");
scanf("%s",fileName);
getchar();
//组装请求包
short *p1=(short*)buf;
*p1=htons(2); //1下载/2上传
char *p2=buf+2; //文件名段
strcpy(p2,fileName);
char *p4=p2+strlen(p2)+1; //模式段
strcpy(p4,"octet");
int size=4+strlen(p2)+strlen(p4); //要发送数据的大小
//向服务器发送下载请求
if(sendto(cfd,buf,size,0,(struct sockaddr*)&sin,sizeof(sin))==-1)
{
perror("sendto error");
return -1;
}
printf("请求成功\n");
int rfd;
if((rfd=open(fileName,O_RDONLY))==-1)
{
perror("open error");
return -1;
}
//循环接收回复服务器发来的消息
while(1)
{
//接收服务器发送的ACK
bzero(buf,sizeof(buf));
//接收服务器发送的ACK
if(recvfrom(cfd,buf,4,0,(struct sockaddr*)&sin,&socklen)==-1)
{
perror("ACK recvfrom error");
return -1;
}
printf("ACK返回成功\n");
//ACK组装
short *j1=(short *)buf;
//块编号段
short *j2=(short *)buf+2;
//上传数据包
bzero(buf,sizeof(buf));
//拆分数据包
//操作码段
short *q1=(short *)buf;
*q1=htons(3);
//得到块编号
short *q2=q1+2; //*q2为块编号
*q2=*j2;
//数据段为0则下载完成退出循环
char *q3=buf+4;
if(strlen(q3)<=0)
{
break;
}
read(rfd,q3,sizeof(q3));
if(sendto(cfd,buf,size,0,(struct sockaddr*)&sin,sizeof(sin))==-1)
{
perror("sendto error");
return -1;
}
}
}
int main(int argc, const char *argv[])
{
if(argc!=2)
{
printf("input error\n");
return -1;
}
//创建用于接受连接的套接字
int cfd=socket(AF_INET,SOCK_DGRAM,0);
if(cfd==-1)
{
perror("socket error");
return -1;
}
printf("socket success cfd=%d\n",cfd);
//填充要绑定的地址信息结构体
struct sockaddr_in sin;
sin.sin_family=AF_INET;
sin.sin_port=htons(69);
sin.sin_addr.s_addr=inet_addr(argv[1]);
int mune=-1;
while(1)
{
system("clear");
printf("\t\t=====1、下载=====\n");
printf("\t\t=====2、上传=====\n");
printf("\t\t=====0、退出=====\n");
printf("请输入功能:");
scanf("%d",&mune);
getchar();
switch(mune)
{
case 1:Do_download(cfd,sin);break;
case 2:Do_upload(cfd,sin);break;
case 0:goto POS;
default:printf("输入错误,请输入1、2、0\n");
}
//阻塞
printf("按回车键清空\n");
while(getchar()!='\n');
}
POS:
//关闭套接字
close(cfd);
return 0;
}