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 实现客户端和服务端 写完了客户端和服务端,那么如何实现客户端和服务端的 ...
随机推荐
- 基于Redis&MySQL接口幂等性设计
基于Redis&MySQL接口幂等性设计 欲把相思说似谁,浅情人不知. 1.幂等 幂等性即多次调用接口或方法不会改变业务状态,可以保证重复调用的结果和单次调用的结果一致. 2.幂等使用场景 前 ...
- 权限修饰符和final关键字
public 不受任何限制,可以被其他任何类访问 一个JAVA文件只能包含一个public文件 java将public类作为每个编译单元的数据接口 只能有一个接口 private 只能在自己类中访问 ...
- kibana 对es的简单操作。
一.查询和查看. #1.查询所有的数据 GET _search { "query": { "match_all":{} } } #2. 查看ES集群的健康状态 ...
- NumPy 教程目录
NumPy 教程目录 1 Lesson1--NumPy NumPy 安装 2 Lesson2--NumPy Ndarray 对象 3 Lesson3--NumPy 数据类型 4 Lesson4--Nu ...
- CF1229D - Wojtek and Card Tricks
做法一 首先将排列用康托展开映射到整数,并且预处理出排列之间乘法的结果,复杂度 \(\mathcal{O}(k(k!) ^ 2)\). 枚举左端点,有可能分段的右端点至多只有 \(k!\) 个,不妨将 ...
- kafka经验
1.kafka集群搭建 解压 配环境变量 修改配置文件 2.编写管理脚本去管理集群 3.kafka常用命令 4.kafka监控 5.分享kafka经验
- android TextView属性详解
RelativeLayout用到的一些重要的属性: 第一类:属性值为true或false android:layout_centerHrizontal 水平居中 android:l ...
- -bash: ./bin/shutdown.sh: /bin/bash^M: bad interpreter: 没有那个文件或目录
为什么会出现这种问题: 1.这个问题的原因就是我们放在服务器的脚步类型是dos,而不是unix类型,所以会导致出现(-bash: ./bin/shutdown.sh: /bin/bash^M: bad ...
- docker | jenkins 实现自动化部署项目,后端躺着把运维的钱挣了!(上)
前言 背景 最近在帮学校导师写项目,团队有4个人,项目前后端分离.如果是选择瀑布式开发:(在约定好接口的情况下)A.B同学写前端,C.D同学写后端,然后约定一个时间统一联调,最后将项目交付安装到客户机 ...
- Git配置多个github账号免密登录
在公司开发中,有时候会存在公司账户跟私人账户共存,并随时需要切换的情况,这种情况下git可以配置多个ssh-key,无缝切换账号. 假如有两个github账号,一个是私人github账号,一个是公司g ...