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 实现客户端和服务端 写完了客户端和服务端,那么如何实现客户端和服务端的 ...
随机推荐
- K8s配置配置存活、就绪和启动探测器
kubelet 使用存活探测器来知道什么时候要重启容器. 例如,存活探测器可以捕捉到死锁(应用程序在运行,但是无法继续执行后面的步骤). 这样的情况下重启容器有助于让应用程序在有问题的情况下更可用. ...
- elasticsearch 申请basic证书
如果elasticsearch使用低于6.3版本的,basic证书默认1个月,需要申请,可使用时间为1年. 申请地址为: https://license.elastic.co/registration ...
- How to check in Windows if you are using UEFI
You might be wondering if Windows is using UEFI or the legacy BIOS, it's easy to check. Just fire up ...
- ApacheCN Golang 译文集 20211025 更新
Go 云原生编程 零.前言 一.现代微服务架构 二.使用 RESTAPI 构建微服务 三.保护微服务 四.使用消息队列的异步微服务架构 五.使用 React 构建前端 六.在容器中部署应用 七.AWS ...
- C#运算符重载---逐步地分析与理解
1.什么是运算符重载 定义:(百科定义)就是把已经定义的.有一定功能的操作符进行重新定义,来完成更为细致具体的运算等功能.操作符重载可以将概括性的抽象操作符具体化,便于外部调用而无需知晓内部具体运算过 ...
- Docker版本Jenkins的使用
一. 什么是Jenkins Jenkins是当前非常流行的一款持续集成工具,可以帮助大家把更新后的代码自动部署到服务器上运行. 二. 为什么用docker版的Jenkins Jenkins主要有三种安 ...
- 使用estimatedRowHeight的优缺点
使用estimatedRowHeight的优缺点 1.优点 1> 可以降低tableView:heightForRowAtIndexPath:方法的调用频率 2> 将[计算cell高度的操 ...
- Swift中类的使用
主要内容 类的介绍和定义 类的属性 类的构造函数 一. 类的介绍和定义 Swift也是一门面向对象开发的语言 面向对象的基础是类,类产生了对象 在Swift中如何定义类呢? class是Swift中的 ...
- NSMutableString常用方法
1.NSMutableString常用方法 - (void)appendString:(NSString *)aString; 拼接aString到最后面 NSMutableString *strM ...
- 开发时Blocks跟Delegates如何选择----董鑫
1.大多数delegate protocols 都拥有几个消息源. 以GKMatch为例(A GKMatch object provides a peer-to-peer network betwee ...