Toggle navigation
首页
问答
文章
积分商城
专家
专区
更多专区...
文档中心
返回主站
搜索
提问
会员
中心
登录
注册
网络学习营
【网络编程学习】+清石+任务1 简单聊天客户端
发布于 2018-08-02 10:10:01 浏览:1152
订阅该版
作业要求: 通过编程实现: 1. 使用 login 命令登录上服务器聊天室,并将服务器返回的信息通过串口打印出来 2. 使用 say 命令通知服务器你的个人姓名和作业时间 “My name is Yqiu,I'm doing this job at 20180730”,并 将服务器返回的信息打印出来 3. 使用 look 命令查看聊天室人员,并将服务器返回的信息打印出来 4. 使用 who 命令查看我是谁,并将服务器返回的信息打印出来 5. 使用 say 命令告诉服务器我看到有哪些人在聊天室 6. 使用 say 命令告诉服务器我准备退出了 7. 使用 logout 退出聊天室 由每个人独立完成,完成后将串口打印截图发群里。 开发环境说明:qemu虚拟机环境 env 0.7.0 问题总结: 1. 作为命令行输入时,如果同时作为串口输出,如何切换回命令行呢?好像没办法。网友说回车一下就可以。意识是命令行的线程没有结束。待验证。 2. 连接服务器后,好像时间挺长的,等待每一条命令。调整把命令放在最前面,好像点,接收放在后面。 3. 数据错位,并不是你发一条,服务器就给你回一条对应的信息立即马上,可能会先收到其他信息,所以需要处理,而不只是按顺序进行。Look who时候,发两次数据。 4. Look 时候的的结果,也是有回车换行的,在数据封装的时候也需要处理,否则的话,那些数据都变成了命令。服务器就会返回无法识别。用strtok来实现,但因为strtok实现原理是用/0 替代,就是字符串结束标志,所以不太好用,因为最后发送时候,需要用strlen 来检测字符串长度,这个‘\0’是有影响的。最后直接写个替换程序,把
换成空格 5. 连接失败的话,试着关闭防火墙,并关闭网络共享,再重新打开网络共享。。另外如果是wifi 的话,看看是不是连接到其他网络上,不是之前设置的那个共享的网络了。 6. 刚开始等待很长时间,可能是聊天室没人。换个名字,再试试。```/* * 程序清单:tcp 客户端 * * 这是一个 tcp 客户端的例程 * 导出 tcpclient 命令到控制终端 * 命令调用格式:tcpclient URL PORT * URL:服务器地址 PORT::端口号 * 程序功能:接收并显示从服务端发送过来的信息,接收到开头是 'q' 或 'Q' 的信息退出程序 */ #include
#include
/* 使用BSD socket,需要包含socket.h头文件 */ #include "netdb.h" #define BUFSZ 1024 #define MYID "666765" static const char *command[7]= { "login 666765
", // "say what are you doing
", "say My name is fanxiaojie,I'm doing the job at 20180801
", "look
", "who
", "say i can seen ", "say I am quiting
", "logout
" }; void command_test(int sock,char *command,char *recv_data) { int ret; // rt_kprintf("the command is: %s the length is %d
",command,strlen(command)); rt_kprintf("
send error,close the socket.
"); rt_free(recv_data); // break; } else if (ret == 0) { /* 打印send函数返回值为0的警告信息 */ rt_kprintf("
Send warning,send function return 0.
"); } } static const char send_data[] = "This is TCP Client from RT-Thread."; /* 发送用到的数据 */ char look[50]; void tcpclient(int argc, char **argv) { int ret; char *recv_data; struct hostent *host; int sock, bytes_received; struct sockaddr_in server_addr; const char *url; int port; int command_count =0; /* if (argc < 3) { rt_kprintf("Usage: tcpclient URL PORT
"); rt_kprintf("Like: tcpclient 192.168.12.44 5000
"); return ; }*/ url = "183.193.243.90";//argv[1]; port = 11222;//strtoul(argv[2], 0, 10); /* 通过函数入口参数url获得host地址(如果是域名,会做域名解析) */ host = gethostbyname(url); /* 分配用于存放接收数据的缓冲 */ recv_data = rt_malloc(BUFSZ); if (recv_data == RT_NULL) { rt_kprintf("No memory
"); return; } /* 创建一个socket,类型是SOCKET_STREAM,TCP类型 */ if ((sock = socket(AF_INET, SOCK_STREAM, 0)) == -1) { /* 创建socket失败 */ rt_kprintf("Socket error
"); /* 释放接收缓冲 */ rt_free(recv_data); return; } /* 初始化预连接的服务端地址 */ server_addr.sin_family = AF_INET; server_addr.sin_port = htons(port); server_addr.sin_addr = *((struct in_addr *)host->h_addr); rt_memset(&(server_addr.sin_zero), 0, sizeof(server_addr.sin_zero)); /* 连接到服务端 */ if (connect(sock, (struct sockaddr *)&server_addr, sizeof(struct sockaddr)) == -1) { /* 连接失败 */ rt_kprintf("Connect fail!
"); closesocket(sock); /*释放接收缓冲 */ rt_free(recv_data); return; } bytes_received = recv(sock, recv_data, BUFSZ - 1, 0); recv_data[bytes_received] = '\0'; /* 在控制终端显示收到的数据 */ rt_kprintf("
Received data = %s", recv_data); char lookstring[100]; rt_bool_t start_send = 1; while (1) { if((command_count < 7)&&(start_send == 1)) { if (command_count == 4) //i can see { rt_sprintf(&lookstring[0],"%s%s in this room
",command[command_count],look); command_test(sock,lookstring,recv_data); } // rt_kprintf("command_count is %d
",command_count); else { command_test(sock,command[command_count],recv_data); } start_send = 0; } /* 从sock连接中接收最大BUFSZ - 1字节数据 */ bytes_received = recv(sock, recv_data, BUFSZ - 1, 0); if (bytes_received < 0) { /* 接收失败,关闭这个连接 */ closesocket(sock); rt_kprintf("
received error,close the socket.
"); /* 释放接收缓冲 */ rt_free(recv_data); break; } else if (bytes_received == 0) { /* 默认 recv 为阻塞模式,此时收到0认为连接出错,关闭这个连接 */ closesocket(sock); rt_kprintf("
received error,close the socket.
"); /* 释放接收缓冲 */ rt_free(recv_data); break; } /* 有接收到数据,把末端清零 */ recv_data[bytes_received] = '\0'; char *chartemp; if (strncmp(recv_data, "q", 1) == 0 || strncmp(recv_data, "Q", 1) == 0) { /* 如果是首字母是q或Q,关闭这个连接 */ closesocket(sock); rt_kprintf("
got a 'q' or 'Q',close the socket.
"); /* 释放接收缓冲 */ rt_free(recv_data); break; } else { /* 在控制终端显示收到的数据 */ rt_kprintf("
Received data = %s", recv_data); if (command_count ==2) //look //The following are in this room: { if(rt_strstr(recv_data,MYID) != NULL) { //chartemp=strchr(recv_data,':'); // rt_strncpy(look,chartemp,strlen(chartemp)); rt_strncpy(look,recv_data,strlen(recv_data));//strlen(recv_data)); replace(look); rt_kprintf("look[] is %s
",look); command_count++; start_send = 1; } } else if (command_count ==3) { if(rt_strstr(recv_data,MYID) != NULL) { command_count++; start_send = 1; } } else { command_count++; start_send = 1; } } /* 发送数据到sock连接 */ /* ret = send(sock, send_data, strlen(send_data), 0); if (ret < 0) { /* 接收失败,关闭这个连接 closesocket(sock); rt_kprintf("
send error,close the socket.
"); rt_free(recv_data); break; } else if (ret == 0) { /* 打印send函数返回值为0的警告信息 rt_kprintf("
Send warning,send function return 0.
"); }*/ /*if(command_count < 7) { // rt_kprintf("command_count is %d
",command_count); command_test(sock,&command[command_count],recv_data); command_count++; }*/ } return; } MSH_CMD_EXPORT(tcpclient, a tcp client sample); void replace(char *src_data) { int i=0; while (i
') || (src_data* != ' ')) { i++; } else { src_data*=" "; } } } ``` 下载附件 [第一周任务:聊天客户端.pdf](https://oss-club.rt-thread.org/uploads/201808/02/100920iwnxjelwixnxuz4j.attach)
查看更多
0
个回答
默认排序
按发布时间排序
暂无答案,快来添加答案吧
撰写答案
登录
注册新账号
关注者
0
被浏览
1.2k
关于作者
小住住
这家伙很懒,什么也没写!
提问
127
回答
124
被采纳
2
关注TA
发私信
相关问题
1
【LWIP学习营】第一关开发环境搭建
2
LWIP学习营第一周入门移植问题汇总贴
3
【LWIP学习营】f407+lan8720A小结
4
【LwIP学习营】【第一周】仅零散记录,无主题
5
【LWIP学习营】正点原子探索者F407+LAN8720第一周小结
6
【LwIP学习营】【第一周】网络通信基础及实现TCP 聊天客户端
7
【LwIP学习营】【第一周】LWIP移植
8
【LwIP学习营】【第一周】LWIP移植
9
【LwIP学习营】【第一周】开发板适配
10
【LwIP学习营】【第一周】环境搭建和配置验证
推荐文章
1
RT-Thread应用项目汇总
2
玩转RT-Thread系列教程
3
机器人操作系统 (ROS2) 和 RT-Thread 通信
4
国产MCU移植系列教程汇总,欢迎查看!
5
五分钟玩转RT-Thread新社区
6
【技术三千问】之《玩转ART-Pi》,看这篇就够了!干货汇总
7
关于STM32H7开发板上使用SDIO接口驱动SD卡挂载文件系统的问题总结
8
STM32的“GPU”——DMA2D实例详解
9
RT-Thread隐藏的宝藏之completion
10
【ART-PI】RT-Thread 开启RTC 与 Alarm组件
最新文章
1
[RA8D1-Vision Board] sd卡实践
2
FRDM-MCXN947开发板之RGB LED驱动
3
NXP MCXN947 测评(2)基于GPIO 控制实现DHT11 温湿度采集
4
RT-Thread Vision Board - Bare Metal Project with VSCode/PyOCD/Cortex-Debug
5
【学习分享】libc切换 -- 从newlib切换到mlibc
热门标签
RT-Thread Studio
串口
LWIP
Env
SPI
Bootloader
AT
ART-Pi
Hardfault
CAN总线
FinSH
USB
文件系统
DMA
RT-Thread
SCons
线程
RT-Thread Nano
MQTT
STM32
RTC
FAL
rt-smart
ESP8266
ota在线升级
WIZnet_W5500
I2C_IIC
UART
flash
cubemx
packages_软件包
freemodbus
潘多拉开发板_Pandora
PWM
定时器
ADC
BSP
中断
编译报错
socket
keil_MDK
GD32
MicroPython
msh
Debug
ulog
SFUD
flashDB
SDIO总线
rt_mq_消息队列_msg_queue
本月问答贡献
用户名由3_15位
19
个答案
3
次被采纳
踩姑娘的小蘑菇
16
个答案
3
次被采纳
xiaorui
7
个答案
3
次被采纳
sakumisu
5
个答案
3
次被采纳
三世执戟
32
个答案
1
次被采纳
本月文章贡献
比特饼干
3
篇文章
10
次点赞
Z_Y
2
篇文章
5
次点赞
xusiwei1236
2
篇文章
3
次点赞
yinxiangxv
2
篇文章
3
次点赞
Alipay
2
篇文章
3
次点赞
回到
顶部
发布
问题
分享
好友
手机
浏览
扫码手机浏览
投诉
建议
回到
底部