赞
踩
很多时候网联网卡和服务器后台是通过TCP来连接的,这个往往是自定义的协议,而不是HTTP,当然这里可以使用别人提供的TCP服务器,比如:http://www.tongxinmao.com/App/Detail/id/1,这种方式最大的缺点就是太多人用造成很难监听到自己的数据,所以这里介绍怎么在自己的服务器上做这个TCP测试:
1.开放TCP端口,比如这里我自定义一个7013的端口:
2.使能这个端口,因为我使用的是Ubuntu的服务器,所以通过这个命令使能:
sudo ufw allow 7013
之后可以通过如下命令判断是否打开了这个端口:sudo ufw status
root@VM-12-17-ubuntu:~# sudo ufw status Status: active To Action From -- ------ ---- 80 ALLOW Anywhere 9000 ALLOW Anywhere 16990 ALLOW Anywhere 27017 DENY Anywhere 19280 DENY Anywhere 22 ALLOW Anywhere 8080 ALLOW Anywhere 8081 ALLOW Anywhere 443 ALLOW Anywhere 3306 ALLOW Anywhere 7013 ALLOW Anywhere 80 (v6) ALLOW Anywhere (v6) 9000 (v6) ALLOW Anywhere (v6) 16990 (v6) ALLOW Anywhere (v6) 27017 (v6) DENY Anywhere (v6) 19280 (v6) DENY Anywhere (v6) 22 (v6) ALLOW Anywhere (v6) 8080 (v6) ALLOW Anywhere (v6) 8081 (v6) ALLOW Anywhere (v6) 443 (v6) ALLOW Anywhere (v6) 3306 (v6) ALLOW Anywhere (v6) 7013 (v6) ALLOW Anywhere (v6)
3.使用如下命令监听我们想要的端口:
nc -lvnp 7013
4.用客户端连接上服务器:
5.这时候客户端可以点击发送按钮向服务器发送数据:
6.服务器这边直接在中断输入数据然后按回车即可向客户端发送数据:
关于MN316_OPEN物联网平台环境的搭建请看文章:https://blog.csdn.net/chengdong1314/article/details/127265778
这里结合上面的TCP说明测试步骤如下:
因为在收到MN316_OPEN的数据后要在比较短的时间内回应数据,所以这里在监听端口后先把数据准备好,当收到MN316_OPEN发送过来的数据后立即按下回车键,这样数据就会发送到MN316_OPEN!
服务器编写程序自动回复客户端的数据
在上面的测试流程中要在服务器客户端手动输入返回的数据,这个明显不是我想要的,我想要的是自动回复客户端的数据而不是还要手动操作服务端.
这里把仓库https://gitee.com/samson10/tcp_-connection/tree/master的代码上传到服务器中:
使用如下命令编译server_multi_process.c文件:gcc server_multi_process.c -o tcpserver
chmod +x ./tcpserver //给程序加上可执行权限
nohup ./tcpserver & //后台运行server_multi_process
这时候客户端就可以连接服务器并且客户端发送什么数据,服务端就返回什么数据,server_multi_process.c源码如下:
#include <stdio.h> #include<arpa/inet.h> #include<unistd.h> #include<stdlib.h> #include<string.h> #include<errno.h> #include<signal.h> #include<wait.h> void recyleChild(int arg){ //回收资源 while(1){ int ret = waitpid(-1, NULL, WNOHANG); if(ret == -1){ //所有的子进程都回收完了 break; } else if(ret == 0){ //还有子进程活着 break; } else{ printf("子进程 %d 被回收了!\n",ret); } } } int main(){ struct sigaction act; act.sa_flags = 0; sigemptyset(&act.sa_mask); act.sa_handler = recyleChild; printf("server_multi_process\n"); //注册信号捕捉 sigaction(SIGCHLD, &act, NULL); //1、创建socket int lfd = socket(PF_INET, SOCK_STREAM, 0); if(lfd == -1){ perror("socket"); exit(-1); } //2、绑定 struct sockaddr_in saddr; saddr.sin_family = AF_INET; saddr.sin_port = htons(7013); saddr.sin_addr.s_addr = INADDR_ANY; int ret = bind(lfd,(struct sockaddr *)&saddr, sizeof(saddr)); if(ret == -1){ perror("bind"); exit(-1); } //3、监听 ret = listen(lfd, 128); if(ret == -1){ perror("listen"); exit(-1); } //4、不断的循环,等待客户端连接 while(1){ struct sockaddr_in cliaddr; int len = sizeof(cliaddr); //接受连接,获得一个通信的文件描述符 int cfd = accept(lfd, (struct sockaddr*)&cliaddr, &len); if(cfd == -1){ if(errno == EINTR){ continue; } perror("accept"); exit(-1); } //每连接一个进来,创建一个子进程跟客户端通信 pid_t pid = fork(); if(pid == 0){ //说明是子进程,子进程进行的操作:获取客户端的信息 char cliIP[16]; inet_ntop(AF_INET, &cliaddr.sin_addr.s_addr, cliIP, sizeof(cliIP)); unsigned short cliPort = ntohs(cliaddr.sin_port); printf("client ip: %s, client port: %d\n", cliIP, cliPort); //接受客户端发来的数据 char recvBuf[1024] = {0}; while(1){ int datalen = read(cfd, &recvBuf, sizeof(recvBuf)); if(datalen == -1){ perror("read"); exit(-1); } else if(datalen > 0){ printf("receive client data: %s\n", recvBuf); } else{ printf("client closed..."); break; } //将收到的数据返回给客户端 write(cfd, recvBuf, strlen(recvBuf)); } close(cfd); } } close(lfd); return 0; }
测试功能正常,如下:
Copyright © 2003-2013 www.wpsshop.cn 版权所有,并保留所有权利。