1、机械臂
#include <myhead.h>
#define SER_IP "192.168.125.32" //服务器端IP
#define SER_PORT 8888 //服务器端端口号
#define CLI_IP "192.168.68.148" //客户端IP
#define CLI_PORT 9999 //客户端端口号
/**********************TCP客户端********************/
int main(int argc, const char *argv[])
{
//1.创建用于通信的套接字
int cfd=-1;
if((cfd=socket(AF_INET,SOCK_STREAM,0))==-1){
perror("socket error");
return -1;
}
printf("cfd=%d\n",cfd);
//将端口号快速重用
int reuse = 1;
if(setsockopt(cfd, SOL_SOCKET, SO_REUSEADDR, &reuse, sizeof(reuse)) == -1)
{
perror("reuse error");
return -1;
}
printf("reuse success\n");
//2.绑定服务器IP地址和端口号(非必须)
//2.1填充地址信息结构体
struct sockaddr_in cin;
cin.sin_family=AF_INET;
cin.sin_port=htons(CLI_PORT);
cin.sin_addr.s_addr=inet_addr(CLI_IP);
//2.2绑定
if(bind(cfd,(struct sockaddr*)&cin,sizeof(cin))==-1){
perror("bind error");
}
printf("bind success\n");
//3.连接服务器
//3.1填充要连接的服务器的地址信息结构体
struct sockaddr_in sin;
sin.sin_family=AF_INET;
sin.sin_port=htons(SER_PORT);
sin.sin_addr.s_addr=inet_addr(SER_IP);
//3.2连接到服务器
if(connect(cfd,(struct sockaddr*)&sin,sizeof(sin))==-1){
perror("connect error");
return -1;
}
//4.进行数据的收发操作
char rbuf[5]={0xff,0x02,0x00,0x00,0xff}; //红色机械臂
unsigned char bbuf[5]={0xff,0x02,0x01,0x00,0xff}; //蓝色机械臂
//发送给服务器当做初始值
send(cfd,rbuf,sizeof(rbuf),0);
sleep(1); //防止沾包
send(cfd,bbuf,sizeof(bbuf),0);
char key=0; //定义键盘输入的值
while(1)
{
scanf("%c",&key);
getchar(); //吸收垃圾字符
switch(key)
{
case 'w':
{
rbuf[3] += 2; //红色机械臂每次增加3度
if(rbuf[3]>=90){
rbuf[3]=90;
}
send(cfd,rbuf,sizeof(rbuf),0); //将键盘控制的结果发送到服务器端
}
break;
case 's':
{
rbuf[3] -= 2;
if(rbuf[3]<=-90){
rbuf[3]=-90;
}
send(cfd,rbuf,sizeof(rbuf),0);
}
break;
case 'd':
{
bbuf[3]+=2;
if(bbuf[3]>=180)
{
bbuf[3]=180;
}
send(cfd,bbuf,sizeof(bbuf),0);
}
break;
case 'a':
{
bbuf[3]+=2;
if(bbuf[3]<=0)
{
bbuf[3]=0;
}
send(cfd,bbuf,sizeof(bbuf),0);
}
break;
default:printf("error\n");break;
}
}
//5.关闭套接字
close(cfd);
return 0;
}
2、基于UDP的tftp通信
#include<myhead.h>
#define SER_IP "192.168.125.32"
#define SER_PORT 69
//定义下载函数
int download(int cfd, struct sockaddr_in sin)
{
//组件协议包:下载请求
char pack[516]="";
short *p1 = (short *)pack;
*p1 = htons(1); //设置操作码
char *p2 = pack+2;
char file[20] = "";
printf("请输入要下载的文件名:");
fgets(file, sizeof(file), stdin);
file[strlen(file)-1] = 0;
strcpy(p2, file); //文件名
char *p4 = p2 +strlen(p2) + 1;
strcpy(p4, "octet"); //模式位
int packlen = 4 + strlen(p2) + strlen(p4); //请求包的大小
//向服务器发送请求包
sendto(cfd, pack ,packlen,0, (struct sockaddr*)&sin, sizeof(sin));
struct sockaddr_in cin;
socklen_t socklen = sizeof(cin); //计算客户端地址信息结构体的大小
//打开文件
int wfd = -1;
if((wfd = open(file,O_WRONLY|O_CREAT|O_TRUNC,0664)) == -1)
{
perror("open error");
return -1;
}
while(1)
{
//收取服务器发来的数据包
//清空协议包
bzero(pack, sizeof(pack));
int res = recvfrom(cfd, pack, sizeof(pack), 0, (struct sockaddr*)&cin,&socklen);
//判断操作码是否为3 以及数据包数据内容是否为512字节
if(*p1 == ntohs(3))
{
//将数据包写入文件
write(wfd, pack+4, res-4);
//回复一个应答包
sendto(cfd, pack, 4, 0,(struct sockaddr*)&cin, sizeof(cin));
//若数据内容小于512字节,读取数据后结束接受数据
if(res-4 < 512)
{
printf("download success\n");
break;
}
}
else if(*p1 == ntohs(5))
{
printf("error\n");
break;
}
}
//关闭文件
close(wfd);
return 0;
}
int upload(int cfd,struct sockaddr_in sin)
{
//组件协议包:下载请求
char pack[516]="";
short *p1 = (short *)pack;
*p1 = htons(1); //设置操作码
char *p2 = pack+2;
char file[20] = "";
printf("请输入要下载的文件名:");
fgets(file, sizeof(file), stdin);
file[strlen(file)-1] = 0;
strcpy(p2, file); //文件名
char *p4 = p2 +strlen(p2) + 1;
strcpy(p4, "octet"); //模式位
int packlen = 4 + strlen(p2) + strlen(p4); //请求包的大小
//向服务器发送请求包
sendto(cfd, pack ,packlen, 0, (struct sockaddr*)&sin, sizeof(sin));
struct sockaddr_in cin;
socklen_t socklen = sizeof(cin); //计算客户端地址信息结构体的大小
//以只读的方式打开文件
int rfd = -1;
if((rfd = open(file,O_RDONLY|O_CREAT|O_TRUNC,0664)) == -1)
{
perror("open error");
return -1;
}
//定义一个块编号
short num = 0;
while(1)
{
//清空协议包
bzero(pack,sizeof(pack));
//接受服务器发来的应答包
int res = recvfrom(cfd,pack,sizeof(pack),0,(struct sockaddr*)&cin,&socklen);
if(*p1 == ntohs(4))
{
//发送一个数据包
*p1 = htons(3);
num++;
*(p1 + 1) = htons(num);
//读取数据
res = read(rfd, p1+2,512);
sendto(cfd, pack, sizeof(pack),0,(struct sockaddr*)&cin,sizeof(cin));
if(res == 0)
{
printf("upload success\n");
break;
}
}
//判断是否为错误包
else if(*p1 == ntohs(5))
{
printf("error\n");
return -1;
}
}
close(rfd);
return 0;
}
int main(int argc, const char *argv[])
{
//创建用于通信的套接字
int cfd = socket(AF_INET, SOCK_DGRAM, 0);
if(cfd == -1)
{
perror("socket error");
return -1;
}
//2、收发数据
//填充服务器的地址信息结构体
struct sockaddr_in sin;
sin.sin_family = AF_INET;
sin.sin_port = htons(SER_PORT);
sin.sin_addr.s_addr = inet_addr(SER_IP);
int key = 0;
while(1)
{
system("clear");
printf("\t************1、下载**********\t\n");
printf("\t************2、上传**********\t\n");
printf("\t************3、退出**********\t\n");
printf("请输入要执行的功能:");
scanf("%d",&key);
getchar();
switch(key)
{
case 1:
{
download(cfd,sin);
}
break;
case 2:
{
upload(cfd,sin);
}
case 3:
{
goto END;
}
break;
default:printf("error\n");break;
}
}
END:
//关闭套接字
close(cfd);
return 0;
}
思维导图: