Toggle navigation
首页
问答
文章
积分商城
专家
专区
更多专区...
文档中心
返回主站
搜索
提问
会员
中心
登录
注册
网络学习营
【网络编程学习】+ 小燕 + TCP聊天客户端
发布于 2018-08-02 00:15:34 浏览:1354
订阅该版
```/* * 程序清单:一个tcp聊天客户端 * 在服务器 183.193.243.90 的 11222 端口 上运行了一个基于 TCP 的简单的聊天服务器 ; 通过编程实现: 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 退出聊天室 参考 Log 信息: Welcome to TestChat
Please log in Use "login "
yqiu: What are you doing?
The following are in this room: yqiu
The following are logged in: yqiu
yqiu: I can see yqiu in the room
yqiu: I am quiting */ #include
#include
/* 使用BSD socket,需要包含socket.h头文件 */ #include "netdb.h" #include
#define BUFSZ 1024 #define TCP_SERVER_IP "183.193.243.90" #define TCP_SERVER_PORT 11222 typedef enum { TCP_CONNECT, LOGIN, IDENTIFY, CHECKMEMBER, WHOAMI, TELLMEMBER, TELLQUIT, LOGOUT, STEP_MAX }_CHAT_STEP; #define CHAT_CMD_LOGIN "login" // 登录上服务器聊天室 #define CHAT_CMD_SAY "say" // 向服务器发送信息 #define CHAT_CMD_LOOK "look" // 查看聊天室人员 #define CHAT_CMD_WHO "who" // 查看我是谁 #define CHAT_CMD_LOGOUT "logout"// 退出聊天室 void tcpclientchat(int argc, char **argv) { int ret; char *recv_data; struct hostent *host; int sock, bytes_received; struct sockaddr_in server_addr; const char *name; _CHAT_STEP chat_step = LOGIN; char send_data[BUFSZ] = {0}; char *members = NULL; if (argc < 2) { rt_kprintf("Usage: login name
"); return ; } name = argv[1]; /* 通过函数入口参数url获得host地址(如果是域名,会做域名解析) */ host = gethostbyname(TCP_SERVER_IP); /* 分配用于存放接收数据的缓冲 */ 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(TCP_SERVER_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; } while (1) { rt_kprintf("recving
"); /* 从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'; /* 在控制终端显示收到的数据 */ rt_kprintf("
%s ", recv_data); switch (chat_step) { case TCP_CONNECT: chat_step++; break; case LOGIN: // 使用 login 命令登录上服务器聊天室 sprintf(send_data, "%s %s
", CHAT_CMD_LOGIN, name); chat_step++; break; case IDENTIFY: // 通知服务器你的个人姓名和作业时间 sprintf(send_data, "%s my name is %s, i'm doing this job at 20180801
", CHAT_CMD_SAY, name); chat_step++; break; case CHECKMEMBER: sprintf(send_data, "%s
", CHAT_CMD_LOOK); chat_step++; break; case WHOAMI: // 记录哪些人在聊天室 members = rt_malloc(bytes_received); if (NULL == members) { rt_kprintf("no memory.
"); break; } memcpy(members, recv_data, bytes_received); sprintf(send_data, "%s
", CHAT_CMD_WHO); chat_step++; break; case TELLMEMBER: sprintf(send_data, "%s I can see %s in this room.
", CHAT_CMD_SAY, members); if (NULL != members) { rt_free(members); } chat_step++; break; case TELLQUIT: sprintf(send_data, "%s I'm quiting.
", CHAT_CMD_SAY); chat_step++; break; case LOGOUT: sprintf(send_data, "%s
", CHAT_CMD_LOGOUT); chat_step++; break; default: chat_step = TCP_CONNECT; break; } /* 发送数据到sock连接 */ if (0 == strlen(send_data)) { continue; } rt_kprintf("%s
", send_data); 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.
"); } memset(send_data, 0, BUFSZ); memset(recv_data, 0, BUFSZ); if (chat_step >= LOGOUT) { closesocket(sock); break; } } return; } MSH_CMD_EXPORT(tcpclientchat, a tcp client chat); ``` 下载附件 [网络编程学习笔记-tcp聊天客户端.docx](https://oss-club.rt-thread.org/uploads/201808/02/001530me17pj711z1zmy77.attach)
查看更多
0
个回答
默认排序
按发布时间排序
暂无答案,快来添加答案吧
撰写答案
登录
注册新账号
关注者
0
被浏览
1.4k
关于作者
lillian
这家伙很懒,什么也没写!
提问
17
回答
49
被采纳
0
关注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
国产MCU移植系列教程汇总,欢迎查看!
4
机器人操作系统 (ROS2) 和 RT-Thread 通信
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
RT-Thread OS应用开发实战线上师资培训通知
2
【ci】【github】【bsp】RT-Thread仓库的CI自动编译测试
3
免费解锁MCU超能力!4月AIoT实战培训三城巡演
4
rt-thread主仓 BSP瘦身指南
5
Studio环境下ST M7系列USB主机(CherryUSB)配置及踩坑
热门标签
RT-Thread Studio
串口
Env
LWIP
SPI
AT
Bootloader
Hardfault
CAN总线
FinSH
ART-Pi
DMA
USB
文件系统
RT-Thread
SCons
RT-Thread Nano
线程
MQTT
STM32
rt-smart
RTC
FAL
I2C_IIC
cubemx
ESP8266
WIZnet_W5500
UART
ota在线升级
PWM
BSP
flash
freemodbus
packages_软件包
潘多拉开发板_Pandora
GD32
定时器
ADC
flashDB
编译报错
socket
中断
rt_mq_消息队列_msg_queue
keil_MDK
Debug
SFUD
msh
ulog
C++_cpp
at_device
本月问答贡献
RTT_逍遥
4
个答案
2
次被采纳
聚散无由
3
个答案
2
次被采纳
踩姑娘的小蘑菇
5
个答案
1
次被采纳
a1012112796
4
个答案
1
次被采纳
YZRD
2
个答案
1
次被采纳
本月文章贡献
出出啊
1
篇文章
2
次点赞
小小李sunny
1
篇文章
1
次点赞
张世争
1
篇文章
2
次点赞
crystal266
2
篇文章
1
次点赞
whj467467222
2
篇文章
1
次点赞
回到
顶部
发布
问题
分享
好友
手机
浏览
扫码手机浏览
投诉
建议
回到
底部