使用WINSOCK的网络通信模拟程序
(服务器端)
最近在做嵌入式的project过程中,学习了winsock网络编程,project主要的内容是在移植到stm32之前通过c语言对整个过程进行模拟;过程包括:一台client端的设备和一台作为服务器端的sensor设备通过TCP协议进行连接,通过client端输入不同指令对sensor端进行控制:
例如start命令唤醒sensor;
唤醒后输入任意指令获得sensor端返回的温度数值(此处为随机数生成);
唤醒后输入quit退出连接,结束模拟过程。
下面是一些说明:
1.sensor端作为服务器,代码分为通讯模块、控制模块、温度模块。
2.考虑到TCP协议通过三次握手进行连接,有助于保证sensor端和client端通信的稳定性,我们使用TCP通信替代了推荐的UDP通信,因此代码部分中大规模的代码是通讯模块。
3.控制模块是对client端的信息进行鉴别(实际上就是设置不同信号的相应优先级,因为project比较简单,此处只设置了三级响应)
4.温度模块在此代码中只是通过随机数生成的35.0-42.9之间的数值,在单片机开发板版本中为通过温度传感器检测到的实际数值。
补充:project的完整源码已经update到gitee,后续的改进将逐步进行,大家感兴趣的话可以看看gitee连接
此处鸣谢一起完成project的负责单片机部分的王同学CSDN个人空间,负责GUI部分的张同学和司马同学
此处为客户机部分文章链接https://blog.csdn.net/capodexi/article/details/106802557
此部分为sensor端源码
#include <stdio.h>
#include<stdlib.h>
#include<time.h>
#include<WINSOCK2.h>
#include<string.h>
#include<iostream>
#include<tchar.h>
#pragma comment(lib,"WS2_32.lib")
#define BUF_SIZE 64
//设置头文件,库文件与常量(缓冲区大小)
int _tmain(int argc, _TCHAR* argv[])
{
WSADATA wsd;
SOCKET sServer;
SOCKET sClient;
SOCKADDR_IN servAddr;
char buf[BUF_SIZE];
int retVal;
//声明程序所需的变量
if (WSAStartup(MAKEWORD(2, 2), &wsd) != 0)
{
printf("WSAStartup failed! \n");
return 1;
}
//初始化Socket环境
sServer = socket(AF_INET, SOCK_STREAM, IPPROTO_TCP);
if (INVALID_SOCKET == sServer)
{
printf("socket failed! \n");
WSACleanup();
return -1;
}
//创建server端的Socket
SOCKADDR_IN addrServ;
addrServ.sin_family = AF_INET;
addrServ.sin_port = htons(9990);
addrServ.sin_addr.S_un.S_addr = htonl(INADDR_ANY);
//设置服务器监听地址为任意本地地址,设置端口号为9990
retVal = bind(sServer, (const struct sockaddr*)&addrServ, sizeof(SOCKADDR_IN));
if (retVal == SOCKET_ERROR)
{
printf("bind failed!\n");
closesocket(sServer);
WSACleanup();
return -1;
}
//绑定SocketServer到本地地址
retVal = listen(sServer, 1);
if (SOCKET_ERROR == retVal)
{
printf("listen failed! \n");
closesocket(sServer);
WSACleanup();
return -1;
}
//在ServerSocket上进行监听
printf("TCP server socket start...\n");
sockaddr_in addrClient;
int addrClientlen = sizeof(addrClient);
sClient = accept(sServer, (sockaddr FAR*) & addrClient, &addrClientlen);
if (sClient == INVALID_SOCKET)
{
printf("accept error!\n ");
closesocket(sServer);
WSACleanup();
return -1;
}
//接受客户端请求
int j = 0;
printf("TCP server syart successfully!\n");
while (true)
{
ZeroMemory(buf, BUF_SIZE);
retVal = recv(sClient, buf, BUFSIZ, 0);
if (SOCKET_ERROR == retVal)
{
printf("recv failed! \n");
closesocket(sServer);
closesocket(sClient);
WSACleanup();
return -1;
}
if (strcmp(buf, "start") != 0 && j == 0)
{
char cls[BUF_SIZE] = "sensor has not worked yet!Please press 'start'!\n ";
strcpy(buf, cls);
retVal = send(sClient, buf, strlen(buf), 0);
if (SOCKET_ERROR == retVal)
{
printf("send failed! \n");
closesocket(sServer);
closesocket(sClient);
WSACleanup();
return -1;
}
j++;
continue;
}//sensor端启动命令检测
if (strcmp(buf, "start") == 0||j == 0)
{
char sta[BUF_SIZE] = "sensor start!";
printf("service start!");
strcpy(buf, sta);
retVal = send(sClient,buf, strlen(buf), 0);
if (SOCKET_ERROR == retVal)
{
printf("send failed! \n");
closesocket(sServer);
closesocket(sClient);
WSACleanup();
return -1;
}
j++;
continue;
}//相应启动命令的输出信息
if (strcmp(buf, "quit") == 0)
{
retVal = send(sClient, "quit", strlen("quit"), 0);
printf("Shutdown command recieved!");
break;
}//exit
int p,q,r;
char msg[BUF_SIZE];
memset(msg, 0, sizeof(msg));
p = rand() % 2 + 3;
if (p==3)
{
q = rand() % 5 + 5;
}
else
{
q = rand() % 3 + 0;
}
r = rand() % 10 + 0;
srand((unsigned)time(NULL));
msg[0]=(char)'0'+p;
msg[1]=(char)'0'+q;
msg[2]=46;
msg[3]=(char)'0'+r;
msg[4]='\0';
//生成随机数,范围35.0-42.0
SYSTEMTIME st;
GetLocalTime(&st);
printf("%4d-%2d-%2d %2d:%2d:%2d, Recv From Client [%s:%d]:%s\n",
st.wYear, st.wMonth, st.wDay, st.wHour, st.wMinute, st.wSecond,
inet_ntoa(addrClient.sin_addr), addrClient.sin_port, "Temprature Sending Now");
if(j>=0)
{
retVal = send(sClient,msg, strlen(msg), 0);
if (SOCKET_ERROR == retVal)
{
printf("send failed! \n");
closesocket(sServer);
closesocket(sClient);
WSACleanup();
return -1;
}
}
}
//服务器与客户端传送信息
closesocket(sServer);
closesocket(sClient);
WSACleanup();
//释放空间
system("pause");
return 0;
system("pause");
return 0;
}
制作不易,感谢您的支持!