STM32F746G-DISCO 使用SOCKET客户端通过网络与电脑通信实验
MDK5提供了BSD Client for STM32F746G-Discovery的例程
打开MDK5的Pack Installer
在右边选STM32F746
左边选择BSD Client (STM32F746G-Discovery)
点Copy选择一个项目的保存路径点OK
我的MDK版本在创建项目后Network是红色的
编译提示Error #540: 'Keil.MDK-Pro::Network:CORE:Release:6.5.0' component is not available for target 'STM32F746 Flash', pack 'Keil.MDK-Middleware.6.5.0' is not selected
遇到这个问题打开”Select Software Packs for Target’STM32F746 Flash’窗口
在弹出的窗口里去掉”Use latest versions of all installed Software Packs”的勾选
展开Keil::MDK-Middleware去掉7.0.0-beta选择6.5.0
打开BSD_Client.c选择Configuration Wizard配置目标Socket服务器的IP和端口号
我的服务器IP设置了192.168.1.19端口1001
在官方的代码里有一个处理Socket的函数
/*----------------------------------------------------------------------------
Thread 'Client': BSD Client socket process
*---------------------------------------------------------------------------*/
static void Client (void const *arg) {
SOCKADDR_IN addr;
int sock, res;
char dbuf[4];
uint8_t p2val,lshf;
while (1) {
sock = socket (AF_INET, SOCKTYPE, 0);
addr.sin_port = htons(PORT_NUM);
addr.sin_family = PF_INET;
addr.sin_addr.s_b1 = IP1;
addr.sin_addr.s_b2 = IP2;
addr.sin_addr.s_b3 = IP3;
addr.sin_addr.s_b4 = IP4;
connect (sock, (SOCKADDR *)&addr, sizeof (addr));
lshf = 1;
p2val = 0x01;
while (1) {
// Shift the LEDs
LED_SetOut (p2val);
p2val = lshf ? (p2val << 1) : (p2val >> 1);
if (p2val == 0x80) lshf = 0;
if (p2val == 0x01) lshf = 1;
// Send the data to LED Server.
dbuf[0] = BLINKLED;
dbuf[1] = p2val;
res = send (sock, (char *)&dbuf, 2, 0);
if (res < 0) {
break;
}
osDelay (100 * SPEED);
}
closesocket (sock);
}
}
原来的函数里没有实现Socket接收函数
为了不影响通信我建了两个线程,一个用于接收,一个用于发送
SOCKADDR_IN addr;
int sock, res = 0;
int startFlag = 0;
static void PrintResult(int result)
{
char * str = " ";
char printStr[60];
switch(res)
{
case BSD_ERROR:
str = "General Error";
break;
case BSD_ERROR_SOCKET:
str = "Invalid socket descriptor";
break;
case BSD_ERROR_PARAMETER:
str = "Invalid parameter";
break;
case BSD_ERROR_WOULDBLOCK:
str = "It would have blocked";
break;
case BSD_ERROR_NOMEMORY:
str = "Not enough memory in memory pool";
break;
case BSD_ERROR_CLOSED:
str = "Connection is closed or aborted";
break;
case BSD_ERROR_LOCKED:
str = "Socket is locked by another thread";
break;
case BSD_ERROR_TIMEOUT:
str = "Socket, Host Resolver timeout";
break;
case BSD_ERROR_INPROGRESS:
str = "Host Name resolving in progress";
break;
case BSD_ERROR_NONAME:
str = "Host Name not existing";
break;
}
strncpy(printStr,str,20);
printStr[20] = '\0';
GLCD_DrawString (5*16, 6*24, (char*)printStr);
strncpy(printStr,str+20,20);
GLCD_DrawString (5*16, 7*24, (char*)printStr);
}
//HOSTENT *gethostbyname (const char *name, int *err);
static void Recevice(void const *arg)
{
char dbuf[50];
while(1)
{
res = recv (sock, (char *)&dbuf, 50, 0);
GLCD_DrawString (5*16, 5*24, (char*)dbuf);
osDelay (100 * SPEED);
PrintResult(res);
}
}
static void Send(void const *arg)
{
char dbuf[50];
uint16_t i;
while (1) {
sock = socket (AF_INET, SOCKTYPE, 0);
addr.sin_port = htons(PORT_NUM);
addr.sin_family = PF_INET;
addr.sin_addr.s_b1 = IP1;
addr.sin_addr.s_b2 = IP2;
addr.sin_addr.s_b3 = IP3;
addr.sin_addr.s_b4 = IP4;
connect (sock, (SOCKADDR *)&addr, sizeof (addr));
while(1)
{
sprintf(dbuf,"STM32F746G-DISCO Send %d",i++);
res = send (sock, dbuf, strlen(dbuf), 0);
osDelay (100 * SPEED);
PrintResult(res);
if(res < 0)
{
break;
}
}
closesocket (sock);
}
}
/*----------------------------------------------------------------------------
Thread 'Client': BSD Client socket process
*---------------------------------------------------------------------------*/
static void Client (void const *arg) {
{
sock = socket (AF_INET, SOCKTYPE, 0);
addr.sin_port = htons(PORT_NUM);
addr.sin_family = PF_INET;
addr.sin_addr.s_b1 = IP1;
addr.sin_addr.s_b2 = IP2;
addr.sin_addr.s_b3 = IP3;
addr.sin_addr.s_b4 = IP4;
osThreadCreate (osThread(Send), NULL);
osThreadCreate (osThread(Recevice), NULL);
}
}
代码写好后下载到开发板
然后编写C#上位机程序
using System;
using System.IO;
using System.Net;
using System.Net.Sockets;
using System.Text;
using System.Threading;
namespace SocketServer
{
class Program
{
private static byte[] result = new byte[1024];
private static int myProt = 1001; //端口
static Socket serverSocket;
static void Main(string[] args)
{
//服务器IP地址
IPAddress ip = IPAddress.Parse("192.168.1.19");
serverSocket = new Socket(AddressFamily.InterNetwork, SocketType.Stream, ProtocolType.Tcp);
serverSocket.Bind(new IPEndPoint(ip, myProt)); //绑定IP地址:端口
serverSocket.Listen(10); //设定最多10个排队连接请求
Console.WriteLine("启动监听{0}成功", serverSocket.LocalEndPoint.ToString());
//收发数据
int i = 0;
Socket clientSocket = serverSocket.Accept();
new Thread((ThreadStart)delegate
{
while (true)
{
try
{
clientSocket.Send(Encoding.ASCII.GetBytes(String.Format("Server Send {0}\0", i++)));
//通过clientSocket接收数据
int receiveNumber = clientSocket.Receive(result);
Console.WriteLine("接收客户端{0}消息:{1}", clientSocket.RemoteEndPoint.ToString(), Encoding.ASCII.GetString(result, 0, receiveNumber));
Thread.Sleep(100);
}
catch (Exception ex)
{
Console.WriteLine(ex.Message);
clientSocket.Shutdown(SocketShutdown.Both);
clientSocket.Close();
}
}
}).Start();
Console.ReadLine();
}
}
}
运行后的效果
上位机