01--c实现基础客户端和服务端与c++ boost.asio实现对比
c实现服务端和客户端交互:
学习查阅的博客:
https://blog.csdn.net/u011068702/article/details/54380259
https://blog.csdn.net/iamhycljc/article/details/6859013
在Terminator中的快捷键,alt+a锁定多个,alt+o取消锁定
c语言中,printf("......\n"); 一定要加\n !!!!!!
编译的时候,加上-Wall -g 前者可以打印错误或警告信息,后者可以用gdb调试
服务端 server.c:
调试方法,在命令行输入:nc 127.0.0.1 port
///c
#include <stdio.h>
#include <unistd.h>
#include <sys/socket.h>
#include <stdlib.h>
#include <netinet/in.h>
#include <arpa/inet.h>
#include <ctype.h>
#include <strings.h> #define SERV_IP "127.0.0.1"//点分十进制类型
#define SERV_PORT 6666//服务端port,不能大于65535(2的16次方),1000以下的端口一般给系统使用,一般3000以上 ///服务端代码:socket --> bind --> listen --> accept --> (read write) --> close两个socket int main(void)
{
int sfd;//用来建立连接的文件描述符
struct sockaddr_in serv_addr;//存储客户端的ip、port
struct sockaddr_in client_addr;
int cfd;//用来和客户端通信的文件描述符 记住,socket都是成对出现的
socklen_t client_addr_len;//listen的传入传出参数
char buf[BUFSIZ];//BUFSIZ 操作系统自带的宏,8K大小
char client_IP[BUFSIZ];
int n;//read 实际读到的字节 //查看方式:linux命令行, man socket
//三个参数: int socket(int domain, int type, int protocol);
//domain: 即地址类型,ipv4或ipv6,即AF_INET或AF_INET6
//type: 用来建立连接的方式,即tcp(默认)或udp
//protocol: 0
sfd = socket(AF_INET, SOCK_STREAM, 0);
//TODO 检测sfd返回值 bzero(&serv_addr, sizeof(serv_addr));//使用serv_addr之前,先初始化,即清空 和memset不同在于,memset可以初始化到任意数值
serv_addr.sin_family = AF_INET;//作用域(类型):ipv4、ipv6、本地套接字 等
serv_addr.sin_port = htons(SERV_PORT);//注意:默认是小端存储,要把本地字节序,转化成网络字节序 int--->二进制0101
//serv_addr.sin_addr.s_addr = inet_pton(SERV_IP);//注意:同理 #include <arpa/inet.h> 字符串--->二进制0101
serv_addr.sin_addr.s_addr = htonl(INADDR_ANY);//区别,一个是int转,一个是字符串转
//serv_addr.sin_addr.s_addr = inet_addr(SERV_IP);//INADDR_ANY就是inet_addr("0.0.0.0")
bind(sfd, (struct sockaddr *)&serv_addr, sizeof(serv_addr));
//std::cout << sizeof(serv_addr) << std::endl; listen(sfd, 128);//参数2:允许最大上限的客户端同时请求连接数 client_addr_len = sizeof(client_addr);
cfd = accept(sfd, (struct sockaddr *)&client_addr, &client_addr_len);//等待客户端连接 阻塞等待
printf("client IP:%s, client port:%d\n",
inet_ntop(AF_INET, &client_addr.sin_addr.s_addr, client_IP, sizeof(client_IP)),
ntohs(client_addr.sin_port)); while(1){
n = read(cfd, buf, sizeof(buf));//从cfd中读,读到的数据都在buf缓存中 n:实际读到的字节
for (int i = 0; i < n; ++i) {
buf[i] = toupper(buf[i]);//小写转大写
}
write(cfd, buf, n);
} close(sfd);
close(cfd); return 0;
}
客户端 client.c:
#include <stdio.h>
#include <unistd.h>
#include <stdlib.h>
#include <sys/socket.h>
#include <arpa/inet.h>
#include <string.h> #define SERV_IP "127.0.0.1"
#define SERV_PORT 6666 int main(void)
{
int cfd;
struct sockaddr_in serv_addr;//这里存的是服务端的ip和port,因为是connect的参数
socklen_t serv_addr_len;
char buf[BUFSIZ];
int n;//读到的字节数 cfd = socket(AF_INET, SOCK_STREAM, 0);//ipv4,流式协议 //linux会随机分配ip给客户端,因此可以不bind memset(&serv_addr, 0, sizeof(serv_addr));//初始化,防止ip的初始值是乱七八糟的 memset:将指针*转换成int
serv_addr.sin_family = AF_INET;
serv_addr.sin_port = htons(SERV_PORT);//大端转小端
//ip:serv_addr.sin_addr.s_addr = inet_addr(SERV_IP);
inet_pton(AF_INET, SERV_IP, &serv_addr.sin_addr.s_addr);
connect(cfd, (struct sockaddr *)&serv_addr, sizeof(serv_addr)); /*在C语言中有strlen和sizeof两个函数求字符数组的长度函数,他们俩的区别就是是否把最后的结束标志也加上去。
strlen是不加的,他表示字符串的长度。
而sizeof求的是字符串在内存中的长度,所以它是加上最后的'\0'的
所以一般而言后者的长度会比前者多1。*/
while (1){
fgets(buf, sizeof(buf), stdin);//类似c++ 中的cin << 将用户的输入写入到buf中 fgets:用户输入hello world --> hello world\n\0
write(cfd, buf, strlen(buf));
n = read(cfd, buf, sizeof(buf));
write(STDOUT_FILENO, buf, n);//写到屏幕上去
} close(cfd); return 0;
}
boost::asio实现服务端和客户端交互:
为cmakelists.txt添加boost组件:https://www.cnblogs.com/magic-428/p/9144492.html
boost::asio的同步和异步方式:https://www.cnblogs.com/lidabo/p/8317196.html
写好的代码编译的时候,一定要加上 -lboost_system 比如:/usr/bin/g++ main.cpp -o test_main -Wall -g -lboost_system
cmakelists.txt(为了在clion中写代码有代码提示)文件写法例如:
cmake_minimum_required(VERSION 2.8)
project( process ) SET(CMAKE_CXX_FLAGS ${CMAKE_CXX_FLAGS} "-std=c++11")
find_package(Boost REQUIRED COMPONENTS
# regex
filesystem # 我的工程中只使用了 boost 的 filesystem 功能,因此这里只有一个组件
system
)
if(NOT Boost_FOUND)
message("Not found Boost")
endif() include_directories(${Boost_INCLUDE_DIRS})
message("${Boost_INCLUDE_DIRS}")
message("${Boost_LIBRARIES}") add_executable( 01_test main.cpp)
target_link_libraries(01_test ${Boost_LIBRARIES})
运行报错,正好学习分析一下,linux下的core dumped这种错误,主要学习,ulimit命令和 gdb <program> core 来调试:
https://www.cnblogs.com/s-lisheng/p/11278193.html
同步方式实现的服务端和客户端:
服务端:
#include <iostream>
#include <boost/asio.hpp> using namespace boost::asio; int main(int argc, char* argv[])
{
// 所有asio类都需要io_service对象
io_service iosev;
ip::tcp::acceptor acceptor(iosev,
ip::tcp::endpoint(ip::tcp::v4(), 6667));//todo 尽量使用3000以上的端口!!! for(;;)
{
// socket对象
ip::tcp::socket socket(iosev);
// 等待直到客户端连接进来
acceptor.accept(socket);
// 显示连接进来的客户端
std::cout << socket.remote_endpoint().address() << std::endl;
//std::cout << socket.remote_endpoint().data() << std::endl; // 向客户端发送hello world!
boost::system::error_code ec;
socket.write_some(buffer("hello world!"), ec);
// 如果出错,打印出错信息
if(ec)
{
std::cout << boost::system::system_error(ec).what() << std::endl;
break;
}
// 与当前客户交互完成后循环继续等待下一客户连接
}
return 0;
}
客户端:
#include <iostream>
#include <boost/asio.hpp>
using namespace boost::asio;
int main(int argc, char* argv[])
{
// 所有asio类都需要io_service对象
io_service iosev;
// socket对象
ip::tcp::socket socket(iosev);
// 连接端点,这里使用了本机连接,可以修改IP地址测试远程连接
ip::tcp::endpoint ep(ip::address_v4::from_string("127.0.0.1"), 6667);
// 连接服务器
boost::system::error_code ec;
socket.connect(ep,ec);
// 如果出错,打印出错信息
if(ec)
{
std::cout << boost::system::system_error(ec).what() << std::endl;
return -1;
}
// 接收数据
char buf[100];
size_t len=socket.read_some(buffer(buf), ec);
// std::cout.write(buf, len);
std::cout.write(buf, len);
std::cout << std::endl;
return 0;
}
01--c实现基础客户端和服务端与c++ boost.asio实现对比的更多相关文章
- Python进阶----SOCKET套接字基础, 客户端与服务端通信, 执行远端命令.
Python进阶----SOCKET套接字基础, 客户端与服务端通信, 执行远端命令. 一丶socket套接字 什么是socket套接字: 专业理解: socket是应用层与TCP/IP ...
- Java基础---Java---网络编程---TCP的传输、客户端和服务端的互访、建立一个文本转换器、编写一个聊天程序
演示TCP的传输的客户端和服务端的互访 需求:客户端给服务端发送数据,服务端收到后,给客户端反馈信息. 客户端: 1.建立Socket服务,指定要连接方朵和端口 2.获取Socket流中的输出流,将数 ...
- Oracle基础知识点——Oracle服务端和客户端
Oracle服务端 服务端提供oracle服务的实例,其是数据库的核心,用于数据库的管理,对象的管理与存储.数据的存储.查询.数据库资源的监控.监听等一些服务. 例子:比如一台机子上安装了Oracle ...
- 客户端获取服务端自定义类数据 z
客户端获取服务端自定义类数据 问题一:超时问题,在最后获取数据的时候突然提示服务超时,服务已断开 解决:配置文件添加: <bindings> <wsHttpBinding> & ...
- Android BLE与终端通信(三)——客户端与服务端通信过程以及实现数据通信
Android BLE与终端通信(三)--客户端与服务端通信过程以及实现数据通信 前面的终究只是小知识点,上不了台面,也只能算是起到一个科普的作用,而同步到实际的开发上去,今天就来延续前两篇实现蓝牙主 ...
- c++ 网络编程(一)TCP/UDP windows/linux 下入门级socket通信 客户端与服务端交互代码
原文作者:aircraft 原文地址:https://www.cnblogs.com/DOMLX/p/9601511.html c++ 网络编程(一)TCP/UDP 入门级客户端与服务端交互代码 网 ...
- java Socket通信,客户端与服务端相互发消息
1.通信过程 网络分为应用层,http.ssh.telnet就是属于这一类,建立在传输层的基础上.其实就是定义了各自的编码解码格式,分层如下: 2.Socket连接 上述通信都要先在传输层有建立连接的 ...
- 实验09——java基于TCP实现客户端与服务端通信
TCP通信 需要先创建连接 - 并且在创建连接的过程中 需要经过三次握手 底层通过 流 发送数据 数据没有大小限制 可靠的传输机制 - 丢包重发 包的顺序的 ...
- java 从零开始手写 RPC (03) 如何实现客户端调用服务端?
说明 java 从零开始手写 RPC (01) 基于 socket 实现 java 从零开始手写 RPC (02)-netty4 实现客户端和服务端 写完了客户端和服务端,那么如何实现客户端和服务端的 ...
随机推荐
- Java方法内联
一.概念 方法内联就是把调用方函数代码"复制"到调用方函数中,减少因函数调用开销的技术 函数调用过程 1.首先会有个执行栈,存储它们的局部变量.方法名.动态连接 2.当一个方法 ...
- Shiro 简单介绍和快速入门。
一.shiro是啥? /* * Shiro ? 安全框架是一个 1.功能强大且易于使用的Java安全框架,可执行身份验证,授权,加密和会话管理,并可用于保护任何应用程序 - 从命令行应用程序,移动应用 ...
- Linux 常见文件管理命令
Linux文件系统 根目录:/ 从根目录开始,下面有一堆小目录 root:根用户的目录 bin:可执行文件命令 etc:配置文件 var:日志 lib:安装包或头文件,库文件 home:所有用户的家目 ...
- 布客·ApacheCN 编程/后端/大数据/人工智能学习资源 2020.7
公告 我们的群共享文件有备份到 IPFS 的计划,具体时间待定. 我们的机器学习群(915394271)正式改名为财务提升群,望悉知. 请关注我们的公众号"ApacheCN",回复 ...
- 「JOI 2015 Final」舞会
「JOI 2015 Final」舞会 略微思考一下即可知该过程可以化为一棵树.(3个贵族中选择1个,即新建一个节点连向这3个贵族). 该树的结点个数为\(2n\). 考虑二分答案mid. 判定的是公主 ...
- [USACO19JAN]Exercise Route P
先让我们探索一下两条非树边以及树边能构成简单环的条件是什么,你会发现将第一条非树边的两个点在树上形成的链记为 \(W_1\),另一条即为 \(W_2\),那么当且仅当 \(W_1, W_2\) 有交时 ...
- Velocity学习
原创:转载需注明原创地址 https://www.cnblogs.com/fanerwei222/p/11790482.html Velocity学习: 1. velocity对大小写敏感 2. ve ...
- 关于final关键字
final修饰基本数据类型时 修饰的变量值不可变 final修饰引用数据类型时 修饰的变量地址不可变 值可变 final修饰一个类中的方法时 不可被子类重写 final修饰一个类时 不可被其他类继承 ...
- mybatis的一对多(collection)
使用图解: 低效率查询: 高效率查询: 1 查询用联合查询 2<collection 里面不写column
- 我们一起来学Shell - shell的循环控制
文章目录 Shell 循环之 for 语句 Shell 循环之 while 语句 Shell 循环之 until 语句 Shell 循环控制 break指令 continue 指令 exit 指令 s ...