文章目录
- 本文主要介绍在hi3861使用TCP进行控制小车,在使用TCP遥控小车之前,需要连接好wifi。
TCP传输控制协议,是一种提供可靠的数据传输的协议,是有连接的,按序传输数据的,面向字节流的,可靠稳定的协议。
TCP通讯设备分为了客户端和服务端,在本文中,在windows上建立服务端,hi3861作为客户端,两者连接手机的wifi进行TCP通讯(一定要在同一网络内)。下文主要介绍hi3861作为客户端建立tcp连接的方法。
- 客户端在连接TCP之前一定要确保连上wifi,而hi3861连接wifi需要亿点点时间,因此建议连接wifi后sleep()几秒钟,让hi3861连接上wifi。 首先创建Socket对象,创建客户端套接字对象。 socket()本次只需要关注参数一和参数二,参数一表示ipv4,参数二表示使用面向连接的套接字(TCP)。 返回值:若创建失败,返回-1。 int socks;socks=socket(AF_INET, SOCK_STREAM, 0); 创建sockaddr_in结构体对象,该对象存放服务端地址的参数,并初始化该对象的成员。 struct sockaddr_in sock_addr = {0}; sock_addr.sin_family = AF_INET; //ipv4 sock_addr.sin_port = PP_HTONS(8888); //IP端口 sock_addr.sin_addr.s_addr = inet_addr("192.168.xx.xx"); //ip地址 connect()连接函数,其功能是完成一个有连接协议的连接过程.上面两步创建的结构体对象都会在这一步使用到,这一步也是TCP连接最为关键的一步。 返回值:若连接成功便返回0,失败则返回-1。 参数一:指定数据发送的套接字。 参数二:指定服务端的地址,使用sockaddr_in结构体对象。 参数三:参数二结构体的长度connect(socks, (struct sockaddr *)&sock_addr, sizeof(sock_addr));上述步骤便完成了hi3861客户端和服务端的连接,我们接下来便可以快乐地和服务端进行收发数据,基于该无线连接的收发数据,我们可以做出各种有意思有趣的东西。 API接口。 发送数据:函数:lwip_write(int s, const void *dataptr, size_t size);参数一:套接字对象,参数二:发送的数据,参数三:数据长度。样例: static const char *buf = "Hello! I'm HI3861 TCP client!!!!!!";lwip_write(socks, buf, strlen(buf)); 接收数据:函数:lwip_read(int fildes, void *buf, size_t nbyte);参数一:套接字对象,参数二:接收的数据,参数三:数据长度。样例: char recv_buf[64];(void)memset_s(recv_buf, sizeof(recv_buf), 0, sizeof(recv_buf));lwip_read(socks, recv_buf, sizeof(recv_buf) - 1); 超时机制:在TCP连接中,recv等函数默认为阻塞模式,就是没有数据传输时便会一直停留在函数里,我们有时不希望一直停在这个函数内,便需要一种超时机制setsockopt(),到达一定时间后即使没有数据也会退出函数.函数:int setsockopt(int s, int level, int optname, void* optval, socklen_t* optlen)。 参数一:指向一个打开的套接口描述字。 参数二:指定选项代码的类型|选项代码的类型|含义|| ---- | ---- ||SOL_SOCKET| 基本套接口||IPPROTO_IP| IPv4套接口||IPPROTO_IPV6|IPv6套接口||IPPROTO_TCP|TCP套接口|。 参数三:选项名称SO_RCVTIMEO:设置接收超时时间。 参数四:选项值。 参数五:参数的长度样例: struct timeval recev_timeout;recev_timeout.tv_sec = 5;recev_timeout.tv_usec = 0;/* 5S Timeout */ret_a = setsockopt(socks, SOL_SOCKET, SO_RCVTIMEO, recev_timeout, sizeof(recev_timeout)); 该函数还有其它许多用法,但本文不过多介绍,需要了解更多可以baidu一下。
-
- // tcp#include <stdio.h>#include "lwip/sockets.h"char recv_buf[64];// io#include "iot_gpio.h"#include <hi_gpio.h>#include <hi_io.h>#define GPIO0 0#define GPIO1 1#define GPIO9 9#define GPIO10 10
- //连接好wifi后/**********************************************/ sleep(5); struct sockaddr_in sock_addr = {0}; int s; sock_addr.sin_family = AF_INET; sock_addr.sin_port = PP_HTONS(_PROT_); sock_addr.sin_addr.s_addr = inet_addr(IP_argv[0]); s = socket(AF_INET, SOCK_STREAM, 0); if (s < 0) { printf("socket false\n"); } int ret_a; ret_a = connect(s, (struct sockaddr *)&sock_addr, sizeof(sock_addr)); if (ret_a != 0) { printf("connect false\n"); } my_car_init(); //小车电机的IO口初始化 while (1) { (void)memset_s(recv_buf, sizeof(recv_buf), 0, sizeof(recv_buf)); ret_a = lwip_read(s, recv_buf, sizeof(recv_buf) - 1); //等待接收服务端发送数据 printf("server:%d!\n", recv_buf[0]); //判断接收的数据是何按键,49对应前进键,50对应后退键,51左键,52右键 if (recv_buf[0] == 49) { car_forward(); printf("car_forward!\n"); } else if (recv_buf[0] == 50) { car_stop(); printf("car stop!"); } else if (recv_buf[0] == 51) { car_left(); } else if (recv_buf[0] == 52) { car_right(); } }
- #define GPIO0 0#define GPIO1 1#define GPIO9 9#define GPIO10 10void my_car_init(void){ //IO口初始化 IoTGpioInit(GPIO0); IoTGpioInit(GPIO1); IoTGpioInit(GPIO10); IoTGpioInit(GPIO9); //IO口复用 hi_io_set_func(GPIO0, HI_IO_FUNC_GPIO_0_GPIO); //在hi_io.h里有定义 hi_io_set_func(GPIO1, HI_IO_FUNC_GPIO_1_GPIO); hi_io_set_func(GPIO10, HI_IO_FUNC_GPIO_10_GPIO); hi_io_set_func(GPIO9, HI_IO_FUNC_GPIO_9_GPIO); //IO口功能设置,输入or输出 IoTGpioSetDir(GPIO0, 1); //1为output输出 IoTGpioSetDir(GPIO1, 1); IoTGpioSetDir(GPIO10, 1); IoTGpioSetDir(GPIO9, 1); //IO口输出电平 IoTGpioSetOutputVal(GPIO0, IOT_GPIO_VALUE1); //VALUE1为高电平,VALUE0为低电平 IoTGpioSetOutputVal(GPIO1, IOT_GPIO_VALUE1); IoTGpioSetOutputVal(GPIO9, IOT_GPIO_VALUE1); IoTGpioSetOutputVal(GPIO10, IOT_GPIO_VALUE1);}void car_stop(void){ IoTGpioSetOutputVal(GPIO0, IOT_GPIO_VALUE1); //左轮 IoTGpioSetOutputVal(GPIO1, IOT_GPIO_VALUE1); //左轮 IoTGpioSetOutputVal(GPIO9, IOT_GPIO_VALUE1); //右轮 IoTGpioSetOutputVal(GPIO10, IOT_GPIO_VALUE1); //右轮}void car_forward(void){ IoTGpioSetOutputVal(GPIO0, IOT_GPIO_VALUE1); IoTGpioSetOutputVal(GPIO1, IOT_GPIO_VALUE0); IoTGpioSetOutputVal(GPIO9, IOT_GPIO_VALUE1); IoTGpioSetOutputVal(GPIO10, IOT_GPIO_VALUE0);}void car_left(void){ IoTGpioSetOutputVal(GPIO0, IOT_GPIO_VALUE0); IoTGpioSetOutputVal(GPIO1, IOT_GPIO_VALUE0); IoTGpioSetOutputVal(GPIO9, IOT_GPIO_VALUE1); IoTGpioSetOutputVal(GPIO10, IOT_GPIO_VALUE0);}void car_right(void){ IoTGpioSetOutputVal(GPIO0, IOT_GPIO_VALUE1); IoTGpioSetOutputVal(GPIO1, IOT_GPIO_VALUE0); IoTGpioSetOutputVal(GPIO9, IOT_GPIO_VALUE1); IoTGpioSetOutputVal(GPIO10, IOT_GPIO_VALUE1);}
- 编译gcc -o server server.c -lwsock32。 运行软件./server IP地址 端口。 #include <stdio.h>#include <stdlib.h>#include <winsock2.h>#include <windows.h>#include <conio.h>int key;int startup(int _port, const char *_ip){ WSADATA ws; WSAStartup(MAKEWORD(2, 2), &ws); int sock = socket(AF_INET, SOCK_STREAM, 0); if (sock < 0) { perror("socket"); exit(1); } struct sockaddr_in local; local.sin_family = AF_INET; local.sin_port = htons(_port); local.sin_addr.s_addr = inet_addr(_ip); int len = sizeof(local); if (bind(sock, (struct sockaddr *)&local, len) < 0) //绑定 { perror("bind"); exit(2); } if (listen(sock, 5) < 0) //允许连接的最大数量为5,监听 { perror("listen"); exit(3); } return sock;}int main(int argc, const char *argv[]){ int listen_sock = startup(atoi(argv[2]), argv[1]); //初始化 //用来接收客户端的socket地址结构体 struct sockaddr_in remote; int len = sizeof(struct sockaddr_in); while (1) { int sock = accept(listen_sock, (struct sockaddr *)&remote, &len); //连接 if (sock < 0) { perror("accept"); continue; } printf("get a client, ip:%s, port:%d\n", inet_ntoa(remote.sin_addr), ntohs(remote.sin_port)); while (1) { key = _getch(); if (key > 31 && key < 127) /*如果不是特殊键*/ { printf("按了 %c 键\n", key); continue; } key = _getch(); if (key == 72) { send(sock, "1", 2, 0); printf("按了 %c 上键\n", key); } else if (key == 80) { send(sock, "2", 2, 0); printf("按了 %c 下键\n", key); } else if (key == 75) { send(sock, "3", 2, 0); printf("按了 %c 左键\n", key); } else if (key == 77) { send(sock, "4", 2, 0); printf("按了 %c 右键\n", key); } } } return 0;}
- 想了解更多关于开源的内容,请访问: 51CTO 开源基础软件社区 https://ost.51cto.com。

本文主要介绍在hi3861使用TCP进行控制小车,在使用TCP遥控小车之前,需要连接好wifi。
TCP传输控制协议,是一种提供可靠的数据传输的协议,是有连接的,按序传输数据的,面向字节流的,可靠稳定的协议。
TCP通讯设备分为了客户端和服务端,在本文中,在windows上建立服务端,hi3861作为客户端,两者连接手机的wifi进行TCP通讯(一定要在同一网络内)。下文主要介绍hi3861作为客户端建立tcp连接的方法。
- 客户端在连接TCP之前一定要确保连上wifi,而hi3861连接wifi需要亿点点时间,因此建议连接wifi后sleep()几秒钟,让hi3861连接上wifi。
- 首先创建Socket对象,创建客户端套接字对象。
- socket()本次只需要关注参数一和参数二,参数一表示ipv4,参数二表示使用面向连接的套接字(TCP)。
- 返回值:若创建失败,返回-1。
int socks;
socks=socket(AF_INET, SOCK_STREAM, 0);
- 创建sockaddr_in结构体对象,该对象存放服务端地址的参数,并初始化该对象的成员。
struct sockaddr_in sock_addr = {0};
sock_addr.sin_family = AF_INET; //ipv4
sock_addr.sin_port = PP_HTONS(8888); //IP端口
sock_addr.sin_addr.s_addr = inet_addr("192.168.xx.xx"); //ip地址
- connect()连接函数,其功能是完成一个有连接协议的连接过程.上面两步创建的结构体对象都会在这一步使用到,这一步也是TCP连接最为关键的一步。
- 返回值:若连接成功便返回0,失败则返回-1。
- 参数一:指定数据发送的套接字。
- 参数二:指定服务端的地址,使用sockaddr_in结构体对象。
- 参数三:参数二结构体的长度connect(socks, (struct sockaddr *)&sock_addr, sizeof(sock_addr));上述步骤便完成了hi3861客户端和服务端的连接,我们接下来便可以快乐地和服务端进行收发数据,基于该无线连接的收发数据,我们可以做出各种有意思有趣的东西。
- API接口。
- 发送数据:
函数:lwip_write(int s, const void *dataptr, size_t size);参数一:套接字对象,参数二:发送的数据,参数三:数据长度。
样例:
static const char *buf = "Hello! I'm HI3861 TCP client!!!!!!";
lwip_write(socks, buf, strlen(buf));
- 接收数据:
函数:lwip_read(int fildes, void *buf, size_t nbyte);参数一:套接字对象,参数二:接收的数据,参数三:数据长度。
样例:
char recv_buf[64];
(void)memset_s(recv_buf, sizeof(recv_buf), 0, sizeof(recv_buf));
lwip_read(socks, recv_buf, sizeof(recv_buf) - 1);
- 超时机制:
在TCP连接中,recv等函数默认为阻塞模式,就是没有数据传输时便会一直停留在函数里,我们有时不希望一直停在这个函数内,便需要一种超时机制setsockopt(),到达一定时间后即使没有数据也会退出函数.函数:int setsockopt(int s, int level, int optname, void* optval, socklen_t* optlen)。
- 参数一:指向一个打开的套接口描述字。
- 参数二:指定选项代码的类型|选项代码的类型|含义|| ---- | ---- ||SOL_SOCKET| 基本套接口||IPPROTO_IP| IPv4套接口||IPPROTO_IPV6|IPv6套接口||IPPROTO_TCP|TCP套接口|。
- 参数三:选项名称SO_RCVTIMEO:设置接收超时时间。
- 参数四:选项值。
- 参数五:参数的长度样例:
struct timeval recev_timeout;
recev_timeout.tv_sec = 5;
recev_timeout.tv_usec = 0;
/* 5S Timeout */
ret_a = setsockopt(socks, SOL_SOCKET, SO_RCVTIMEO, recev_timeout, sizeof(recev_timeout));
socks=socket(AF_INET, SOCK_STREAM, 0);
sock_addr.sin_family = AF_INET; //ipv4
sock_addr.sin_port = PP_HTONS(8888); //IP端口
sock_addr.sin_addr.s_addr = inet_addr("192.168.xx.xx"); //ip地址
函数:lwip_write(int s, const void *dataptr, size_t size);参数一:套接字对象,参数二:发送的数据,参数三:数据长度。
样例:
lwip_write(socks, buf, strlen(buf));
函数:lwip_read(int fildes, void *buf, size_t nbyte);参数一:套接字对象,参数二:接收的数据,参数三:数据长度。
样例:
(void)memset_s(recv_buf, sizeof(recv_buf), 0, sizeof(recv_buf));
lwip_read(socks, recv_buf, sizeof(recv_buf) - 1);
在TCP连接中,recv等函数默认为阻塞模式,就是没有数据传输时便会一直停留在函数里,我们有时不希望一直停在这个函数内,便需要一种超时机制setsockopt(),到达一定时间后即使没有数据也会退出函数.函数:int setsockopt(int s, int level, int optname, void* optval, socklen_t* optlen)。
recev_timeout.tv_sec = 5;
recev_timeout.tv_usec = 0;
/* 5S Timeout */
ret_a = setsockopt(socks, SOL_SOCKET, SO_RCVTIMEO, recev_timeout, sizeof(recev_timeout));
该函数还有其它许多用法,但本文不过多介绍,需要了解更多可以baidu一下。
// tcp
#include <stdio.h>
#include "lwip/sockets.h"
char recv_buf[64];
// io
#include "iot_gpio.h"
#include <hi_gpio.h>
#include <hi_io.h>
#define GPIO0 0
#define GPIO1 1
#define GPIO9 9
#define GPIO10 10
#include <stdio.h>
#include "lwip/sockets.h"
char recv_buf[64];
// io
#include "iot_gpio.h"
#include <hi_gpio.h>
#include <hi_io.h>
#define GPIO0 0
#define GPIO1 1
#define GPIO9 9
#define GPIO10 10
//连接好wifi后
/**********************************************/
sleep(5);
struct sockaddr_in sock_addr = {0};
int s;
sock_addr.sin_family = AF_INET;
sock_addr.sin_port = PP_HTONS(_PROT_);
sock_addr.sin_addr.s_addr = inet_addr(IP_argv[0]);
s = socket(AF_INET, SOCK_STREAM, 0);
if (s < 0)
{
printf("socket false\n");
}
int ret_a;
ret_a = connect(s, (struct sockaddr *)&sock_addr, sizeof(sock_addr));
if (ret_a != 0)
{
printf("connect false\n");
}
my_car_init(); //小车电机的IO口初始化
while (1)
{
(void)memset_s(recv_buf, sizeof(recv_buf), 0, sizeof(recv_buf));
ret_a = lwip_read(s, recv_buf, sizeof(recv_buf) - 1); //等待接收服务端发送数据
printf("server:%d!\n", recv_buf[0]);
//判断接收的数据是何按键,49对应前进键,50对应后退键,51左键,52右键
if (recv_buf[0] == 49)
{
car_forward();
printf("car_forward!\n");
}
else if (recv_buf[0] == 50)
{
car_stop();
printf("car stop!");
}
else if (recv_buf[0] == 51)
{
car_left();
}
else if (recv_buf[0] == 52)
{
car_right();
}
}
/**********************************************/
sleep(5);
struct sockaddr_in sock_addr = {0};
int s;
sock_addr.sin_family = AF_INET;
sock_addr.sin_port = PP_HTONS(_PROT_);
sock_addr.sin_addr.s_addr = inet_addr(IP_argv[0]);
s = socket(AF_INET, SOCK_STREAM, 0);
if (s < 0)
{
printf("socket false\n");
}
int ret_a;
ret_a = connect(s, (struct sockaddr *)&sock_addr, sizeof(sock_addr));
if (ret_a != 0)
{
printf("connect false\n");
}
my_car_init(); //小车电机的IO口初始化
while (1)
{
(void)memset_s(recv_buf, sizeof(recv_buf), 0, sizeof(recv_buf));
ret_a = lwip_read(s, recv_buf, sizeof(recv_buf) - 1); //等待接收服务端发送数据
printf("server:%d!\n", recv_buf[0]);
//判断接收的数据是何按键,49对应前进键,50对应后退键,51左键,52右键
if (recv_buf[0] == 49)
{
car_forward();
printf("car_forward!\n");
}
else if (recv_buf[0] == 50)
{
car_stop();
printf("car stop!");
}
else if (recv_buf[0] == 51)
{
car_left();
}
else if (recv_buf[0] == 52)
{
car_right();
}
}
#define GPIO0 0
#define GPIO1 1
#define GPIO9 9
#define GPIO10 10
void my_car_init(void)
{
//IO口初始化
IoTGpioInit(GPIO0);
IoTGpioInit(GPIO1);
IoTGpioInit(GPIO10);
IoTGpioInit(GPIO9);
//IO口复用
hi_io_set_func(GPIO0, HI_IO_FUNC_GPIO_0_GPIO); //在hi_io.h里有定义
hi_io_set_func(GPIO1, HI_IO_FUNC_GPIO_1_GPIO);
hi_io_set_func(GPIO10, HI_IO_FUNC_GPIO_10_GPIO);
hi_io_set_func(GPIO9, HI_IO_FUNC_GPIO_9_GPIO);
//IO口功能设置,输入or输出
IoTGpioSetDir(GPIO0, 1); //1为output输出
IoTGpioSetDir(GPIO1, 1);
IoTGpioSetDir(GPIO10, 1);
IoTGpioSetDir(GPIO9, 1);
//IO口输出电平
IoTGpioSetOutputVal(GPIO0, IOT_GPIO_VALUE1); //VALUE1为高电平,VALUE0为低电平
IoTGpioSetOutputVal(GPIO1, IOT_GPIO_VALUE1);
IoTGpioSetOutputVal(GPIO9, IOT_GPIO_VALUE1);
IoTGpioSetOutputVal(GPIO10, IOT_GPIO_VALUE1);
}
void car_stop(void)
{
IoTGpioSetOutputVal(GPIO0, IOT_GPIO_VALUE1); //左轮
IoTGpioSetOutputVal(GPIO1, IOT_GPIO_VALUE1); //左轮
IoTGpioSetOutputVal(GPIO9, IOT_GPIO_VALUE1); //右轮
IoTGpioSetOutputVal(GPIO10, IOT_GPIO_VALUE1); //右轮
}
void car_forward(void)
{
IoTGpioSetOutputVal(GPIO0, IOT_GPIO_VALUE1);
IoTGpioSetOutputVal(GPIO1, IOT_GPIO_VALUE0);
IoTGpioSetOutputVal(GPIO9, IOT_GPIO_VALUE1);
IoTGpioSetOutputVal(GPIO10, IOT_GPIO_VALUE0);
}
void car_left(void)
{
IoTGpioSetOutputVal(GPIO0, IOT_GPIO_VALUE0);
IoTGpioSetOutputVal(GPIO1, IOT_GPIO_VALUE0);
IoTGpioSetOutputVal(GPIO9, IOT_GPIO_VALUE1);
IoTGpioSetOutputVal(GPIO10, IOT_GPIO_VALUE0);
}
void car_right(void)
{
IoTGpioSetOutputVal(GPIO0, IOT_GPIO_VALUE1);
IoTGpioSetOutputVal(GPIO1, IOT_GPIO_VALUE0);
IoTGpioSetOutputVal(GPIO9, IOT_GPIO_VALUE1);
IoTGpioSetOutputVal(GPIO10, IOT_GPIO_VALUE1);
}
#define GPIO1 1
#define GPIO9 9
#define GPIO10 10
void my_car_init(void)
{
//IO口初始化
IoTGpioInit(GPIO0);
IoTGpioInit(GPIO1);
IoTGpioInit(GPIO10);
IoTGpioInit(GPIO9);
//IO口复用
hi_io_set_func(GPIO0, HI_IO_FUNC_GPIO_0_GPIO); //在hi_io.h里有定义
hi_io_set_func(GPIO1, HI_IO_FUNC_GPIO_1_GPIO);
hi_io_set_func(GPIO10, HI_IO_FUNC_GPIO_10_GPIO);
hi_io_set_func(GPIO9, HI_IO_FUNC_GPIO_9_GPIO);
//IO口功能设置,输入or输出
IoTGpioSetDir(GPIO0, 1); //1为output输出
IoTGpioSetDir(GPIO1, 1);
IoTGpioSetDir(GPIO10, 1);
IoTGpioSetDir(GPIO9, 1);
//IO口输出电平
IoTGpioSetOutputVal(GPIO0, IOT_GPIO_VALUE1); //VALUE1为高电平,VALUE0为低电平
IoTGpioSetOutputVal(GPIO1, IOT_GPIO_VALUE1);
IoTGpioSetOutputVal(GPIO9, IOT_GPIO_VALUE1);
IoTGpioSetOutputVal(GPIO10, IOT_GPIO_VALUE1);
}
void car_stop(void)
{
IoTGpioSetOutputVal(GPIO0, IOT_GPIO_VALUE1); //左轮
IoTGpioSetOutputVal(GPIO1, IOT_GPIO_VALUE1); //左轮
IoTGpioSetOutputVal(GPIO9, IOT_GPIO_VALUE1); //右轮
IoTGpioSetOutputVal(GPIO10, IOT_GPIO_VALUE1); //右轮
}
void car_forward(void)
{
IoTGpioSetOutputVal(GPIO0, IOT_GPIO_VALUE1);
IoTGpioSetOutputVal(GPIO1, IOT_GPIO_VALUE0);
IoTGpioSetOutputVal(GPIO9, IOT_GPIO_VALUE1);
IoTGpioSetOutputVal(GPIO10, IOT_GPIO_VALUE0);
}
void car_left(void)
{
IoTGpioSetOutputVal(GPIO0, IOT_GPIO_VALUE0);
IoTGpioSetOutputVal(GPIO1, IOT_GPIO_VALUE0);
IoTGpioSetOutputVal(GPIO9, IOT_GPIO_VALUE1);
IoTGpioSetOutputVal(GPIO10, IOT_GPIO_VALUE0);
}
void car_right(void)
{
IoTGpioSetOutputVal(GPIO0, IOT_GPIO_VALUE1);
IoTGpioSetOutputVal(GPIO1, IOT_GPIO_VALUE0);
IoTGpioSetOutputVal(GPIO9, IOT_GPIO_VALUE1);
IoTGpioSetOutputVal(GPIO10, IOT_GPIO_VALUE1);
}
编译gcc -o server server.c -lwsock32。
运行软件./server IP地址 端口。
#include <stdio.h>
#include <stdlib.h>
#include <winsock2.h>
#include <windows.h>
#include <conio.h>
int key;
int startup(int _port, const char *_ip)
{
WSADATA ws;
WSAStartup(MAKEWORD(2, 2), &ws);
int sock = socket(AF_INET, SOCK_STREAM, 0);
if (sock < 0)
{
perror("socket");
exit(1);
}
struct sockaddr_in local;
local.sin_family = AF_INET;
local.sin_port = htons(_port);
local.sin_addr.s_addr = inet_addr(_ip);
int len = sizeof(local);
if (bind(sock, (struct sockaddr *)&local, len) < 0) //绑定
{
perror("bind");
exit(2);
}
if (listen(sock, 5) < 0) //允许连接的最大数量为5,监听
{
perror("listen");
exit(3);
}
return sock;
}
int main(int argc, const char *argv[])
{
int listen_sock = startup(atoi(argv[2]), argv[1]); //初始化
//用来接收客户端的socket地址结构体
struct sockaddr_in remote;
int len = sizeof(struct sockaddr_in);
while (1)
{
int sock = accept(listen_sock, (struct sockaddr *)&remote, &len); //连接
if (sock < 0)
{
perror("accept");
continue;
}
printf("get a client, ip:%s, port:%d\n", inet_ntoa(remote.sin_addr), ntohs(remote.sin_port));
while (1)
{
key = _getch();
if (key > 31 && key < 127) /*如果不是特殊键*/
{
printf("按了 %c 键\n", key);
continue;
}
key = _getch();
if (key == 72)
{
send(sock, "1", 2, 0);
printf("按了 %c 上键\n", key);
}
else if (key == 80)
{
send(sock, "2", 2, 0);
printf("按了 %c 下键\n", key);
}
else if (key == 75)
{
send(sock, "3", 2, 0);
printf("按了 %c 左键\n", key);
}
else if (key == 77)
{
send(sock, "4", 2, 0);
printf("按了 %c 右键\n", key);
}
}
}
return 0;
}


© 版权声明
文章版权归作者所有,未经允许请勿转载。