Linux平台 TCP Socket通信实例,发现用代码注释记笔记也不错

TCP server 阻塞

  1 // 两个进程通过socket进行通信,client需要知道server的,server却不需要实现知道client的。
2 // socket需要知道type和address domain;
3 // address domain:unix domain用于同主机进程间,通过文件系统实现;Internet domain用于两台机器间,需要IP和Port信息。一般2000以下的port保留。
4 // socket type:stream(意味着持续读取,TCP是一种协议)、datagram(一次需要读完整个信息,UDP是一种协议)。
5
6 // port复用机制的理解
7
8 /**
9 stream server
10 1.socket
11 2.bind
12 3.listen
13 4.accept
14 */
15 #include <cstdlib> /* exit() */
16 #include <cstdio> /* perror(): 打印信息+发生错误的原因,可用于定位。 */
17 #include <cstring> /* memset memcpy*/
18 #include <iostream> /* cin cout */
19 #include <sys/types.h> /* 为了满足一些 BSD系统添加头文件*/
20 #include <sys/socket.h> /* socket(); listen(); baccept(); socklen_t */
21 #include <netinet/in.h> /* struct sockaddr_in: 保存socket信息; ntohl(), ntohs(), htonl() and htons()*/
22 #include <unistd.h> /* read() write(), 不是C语言范畴,所以没有cxxxx的实现 */
23 // http://man7.org/linux/man-pages/man2/read.2.html
24 // http://man7.org/linux/man-pages/man2/write.2.html
25
26 /**
27 \brief 错误处理函数
28 */
29 void tzError(const char *msg)
30 {
31 perror(msg);
32 exit(1); // 一般不同原因不同的exit code更为规范
33 }
34
35 /**
36 \brief 主函数
37 */
38 int main(int argc, char *argv[]){
39 // 参数check
40 if (argc < 2) {
41 fprintf(stderr,"ERROR, no [port] arg provided\n");
42 exit(1);
43 }
44 // 生成socke + check
45 int sockfd;
46 sockfd = socket(AF_INET, SOCK_STREAM, 0);
47 // int socket(int domain, int type, int protocol);
48 // http://man7.org/linux/man-pages/man2/socket.2.html
49 // domain:
50 // AF_UNIX 用于本地通信
51 // AF_INET IPv4
52 // AF_INET6 IPv6
53 // type:
54 // SOCK_STREAM 面向连接通信
55 // SOCK_DGRAM 面向无连接通信
56 // protocol:
57 // SOCK_NONBLOCK 非阻塞
58 // SOCK_CLOEXEC 子类不继承父类的socket fd
59 // Return:
60 // 建立的socket:对于server用于监听,对于client用于向指定位置发送
61 if (sockfd < 0){
62 tzError("socket()");
63 }
64 // bind socket + check
65 int port_no = atoi(argv[1]);
66 struct sockaddr_in serv_addr;
67 serv_addr.sin_family = AF_INET; // IPv4
68 serv_addr.sin_addr.s_addr = INADDR_ANY; // 相当于inet_addr("0.0.0.0"),所有网卡。
69 serv_addr.sin_port = htons(port_no); // 需要网络序转换
70 int bind_ret = bind(sockfd,
71 (struct sockaddr*)&serv_addr,
72 sizeof(serv_addr));
73 // int bind(int sockfd, const struct sockaddr *addr, socklen_t addrlen);
74 // http://man7.org/linux/man-pages/man2/bind.2.html
75 // socket()产生sockdf,有了name space(address family)但是没有具体地址,bind完成此任务
76 if( bind_ret<0 ){
77 tzError("bind()");
78 }
79 // listen
80 listen(sockfd,5);
81 // int listen(int sockfd, int backlog);
82 // http://man7.org/linux/man-pages/man2/listen.2.html
83 // listen让sockfd对应的socket成为被动socket,用于accetp
84 // backlog: 最大可以入队等待处理的连接数量。如果大于128(somaxconn)可能被内核截断,cat /proc/sys/net/core/somaxconn
85 // 如果尝试connect的链接超过backlog,client收到ECONNREFUSED错误,如果有重传机制可能忽略此错误。
86 // accept + check
87 struct sockaddr_in client_addr;
88 socklen_t clilen_len = sizeof(client_addr);
89 int new_sockfd = accept(sockfd,
90 (struct sockaddr *) &client_addr,
91 &clilen_len);
92 // int accept(int sockfd, struct sockaddr *addr, socklen_t *addrlen)
93 // http://man7.org/linux/man-pages/man2/accept.2.html
94 // 用于面向连接socket(SOCK_STREAM, SOCK_SEQPACKET),提取队列中第一个请求,创建新的connected socket
95 // 返回新创建的socket的fd,原始的被动sockfd不受影响。
96 // addr: socketaddr指针,记录peer的信息,信息格式取决于socket的定义。
97 // 如果等待队列为空,且socket没有设置nonblocking-->阻塞等待;
98 // 如果等待队列为空,且socket设置nonblocking,返回错误:EAGAIN or EWOULDBLOCK
99
100 // 为了处理对socket的新的connect,可使用:select(2), poll(2), or epoll(7)-->有尝试连接的请求会出触发"readable event"
101 // 也可以通过socket()设置发送SIGIO中断。
102 // addrlen:传入传输参数,实际的大小会重新保存到addrlen中
103 if (new_sockfd < 0)
104 tzError("accept()");
105 // 接收-发送信息
106 #define RECV_BUF_SIZE 256
107 char buffer[RECV_BUF_SIZE];
108 std::memset(buffer, 0, RECV_BUF_SIZE); // 用0进行set
109 int valread = read( new_sockfd , buffer, RECV_BUF_SIZE);
110 std::cout << "read:" << valread << "char, content: " << buffer << std::endl;
111 write(new_sockfd , "get msg", 7);
112 // close sockets
113 close(new_sockfd);
114 close(sockfd);
115
116 return 0;
117 }
118
119 // ref:
120 // https://www.cnblogs.com/fuchongjundream/p/3914696.html
121 // http://www.linuxhowtos.org/C_C++/socket.htm
122 //

TCP Client - 单次连接发送接收测试

  1 // 两个进程通过socket进行通信,client需要知道server的,server却不需要实现知道client的。
2 // socket需要知道type和address domain;
3 // address domain:unix domain用于同主机进程间,通过文件系统实现;Internet domain用于两台机器间,需要IP和Port信息。一般2000以下的port保留。
4 // socket type:stream(意味着持续读取,TCP是一种协议)、datagram(一次需要读完整个信息,UDP是一种协议)。
5
6 // port复用机制的理解
7
8 /**
9 stream client
10 1.socket
11 2.connect
12 */
13 #include <cstdlib> /* exit() */
14 #include <cstdio> /* perror(): 打印信息+发生错误的原因,可用于定位。 */
15 #include <cstring> /* memset memcpy strcpy string.c_str()*/
16 #include <iostream> /* cin cout */
17 #include <sys/types.h> /* 为了满足一些 BSD系统添加头文件*/
18 #include <sys/socket.h> /* socket(); listen(); baccept(); socklen_t */
19 // #include <netinet/in.h> /* struct sockaddr_in: 保存socket信息; ntohl(), ntohs(), htonl() and htons()*/
20 #include <netdb.h> /* hostent,IP地址 */
21
22 #include <unistd.h> /* read() write(), 不是C语言范畴,所以没有cxxxx的实现 */
23 // http://man7.org/linux/man-pages/man2/read.2.html
24 // http://man7.org/linux/man-pages/man2/write.2.html
25
26 /**
27 \brief 错误处理函数
28 */
29 void tzError(const char *msg)
30 {
31 perror(msg);
32 exit(1); // 一般不同原因不同的exit code更为规范
33 }
34
35 /**
36 \brief 主函数
37 */
38 int main(int argc, char *argv[]){
39 // 参数check
40 if (argc < 3) {
41 tzError("ERROR, no [IP] [port] arg provided");
42 }
43 // 生成socke + check
44 int sockfd;
45 sockfd = socket(AF_INET, SOCK_STREAM, 0);
46 // int socket(int domain, int type, int protocol);
47 // http://man7.org/linux/man-pages/man2/socket.2.html
48 // domain:
49 // AF_UNIX 用于本地通信
50 // AF_INET IPv4
51 // AF_INET6 IPv6
52 // type:
53 // SOCK_STREAM 面向连接通信
54 // SOCK_DGRAM 面向无连接通信
55 // protocol:
56 // SOCK_NONBLOCK 非阻塞
57 // SOCK_CLOEXEC 子类不继承父类的socket fd
58 // Return:
59 // 建立的socket:对于server用于监听,对于client用于向指定位置发送
60 if (sockfd < 0){
61 tzError("socket()");
62 }
63 // connect + check
64 struct hostent *server;
65 // struct hostent {
66 // char *h_name; /* official name of host */
67 // char **h_aliases; /* alias list */
68 // int h_addrtype; /* host address type */
69 // int h_length; /* length of address */
70 // char **h_addr_list; /* list of addresses */
71 // }
72 // #define h_addr h_addr_list[0] /* for backward compatibility,第一个地址 */
73 server = gethostbyname(argv[1]);
74 if (server == NULL) {
75 tzError("[IP] error");
76 }
77 int port_no = atoi(argv[2]);
78 struct sockaddr_in serv_addr;
79 memset(&serv_addr, 0, sizeof(serv_addr));
80 serv_addr.sin_family = AF_INET; // set type
81 memcpy((char *)server->h_addr, // set addr
82 (char *)&serv_addr.sin_addr.s_addr,
83 server->h_length);
84 serv_addr.sin_port = htons(port_no); // set port
85 int conntect_ret = connect(sockfd,(struct sockaddr *) &serv_addr,sizeof(serv_addr));
86 if(conntect_ret<0){
87 tzError("connect()");
88 }
89
90 // write and read
91 std::cout << "msg>";
92 std::string msg;
93 std::cin >> msg;
94 #define BUF_SIEE 128
95 char buf[BUF_SIEE];
96 memset(buf, 0, BUF_SIEE);
97 strcpy(buf, msg.c_str());
98 int write_n = write(sockfd, buf, msg.size());
99 std::cout << write_n << " chars send." << std::endl;
100 memset(buf, 0, BUF_SIEE); // 用于输出,依赖\0
101 int read_n = read(sockfd, buf, BUF_SIEE);
102 std::cout << buf << std::endl;
103 std::cout << read_n << " chars read." << std::endl;
104
105 // close sockets
106 close(sockfd);
107
108 return 0;
109 }
110
111 // ref:
112 // http://www.linuxhowtos.org/C_C++/socket.htm
113

[C++] Linux TCP Socket 实例- 阻塞的更多相关文章

  1. java tcp socket实例

    java tcp socket实例 2011-04-20 13:58 2364人阅读 评论(1) 收藏 举报 socketjavatcpthreadserverclass package com.ne ...

  2. linux 客户端 Socket 非阻塞connect编程

    开发测试环境:虚拟机CentOS,windows网络调试助手        非阻塞模式有3种用途        1.三次握手同时做其他的处理.connect要花一个往返时间完成,从几毫秒的局域网到几百 ...

  3. Tcp Socket非阻塞recv

    最近看了许多关于网络编程的资料,自己小记一下,以方便以后查找. 什么是阻塞socket,什么是非阻塞socket.对于这个问题,我们要先弄清什么是阻塞/非阻塞.阻塞与非阻塞是对一个文件描述符指定的文件 ...

  4. linux下socket connect 阻塞方式 阻塞时间控制

    同事今天问我,如何在linux下的c代码里面控制connect的阻塞时间.应用的背景是:linux下的c程序有两个目标IP需要connect,如果用阻塞方式,当其中一个IP不能连接的情况下,程序将阻塞 ...

  5. linux下socket编程实例

    linux下socket编程实例一.基本socket函数Linux系统是通过提供套接字(socket)来进行网络编程的.网络的socket数据传输是一种特殊的I/O,socket也是一种文件描述符.s ...

  6. Linux C Socket编程原理及简单实例

    部分转自:http://goodcandle.cnblogs.com/archive/2005/12/10/294652.aspx 1.   什么是TCP/IP.UDP? 2.   Socket在哪里 ...

  7. 从linux源码看socket的阻塞和非阻塞

    从linux源码看socket的阻塞和非阻塞 笔者一直觉得如果能知道从应用到框架再到操作系统的每一处代码,是一件Exciting的事情. 大部分高性能网络框架采用的是非阻塞模式.笔者这次就从linux ...

  8. Linux 下socket通信终极指南(附TCP、UDP完整代码)

    linux下用socket通信,有TCP.UDP两种协议,网上的很多教程把两个混在了一起,或者只讲其中一种.现在我把自己这两天研究的成果汇总下来,写了一个完整的,适合初学者参考,也方便自己以后查阅. ...

  9. linux一切皆文件之tcp socket描述符(三)

    一.知识准备 1.在linux中,一切皆为文件,所有不同种类的类型都被抽象成文件(比如:块设备,socket套接字,pipe队列) 2.操作这些不同的类型就像操作文件一样,比如增删改查等 二.环境准备 ...

  10. linux socket设置阻塞与非阻塞

    非阻塞IO 和阻塞IO: 在网络编程中对于一个网络句柄会遇到阻塞IO 和非阻塞IO 的概念, 这里对于这两种socket 先做一下说明:       基本概念: 阻塞IO:: socket 的阻塞模式 ...

随机推荐

  1. Odoo编程,说明,功能,文章收藏贴

    CN Blog: https://www.cnblogs.com/Firstwing/p/14088500.html #http://blog.sina.com.cn/s/blog_bc7dee2d0 ...

  2. k8s_使用k8s部署博客系统-PV PVC(二)

    PV和PVC PV(PersistentVolume)在声明的时候需要指定大小和续写模式:["ReadWriteMany","ReadWriteOnce",&q ...

  3. Perl报错you may need to install the Win32::Console module(转)

    ActivePerl-5.26.3.XXXX.msi安装后,命令行执行cpan,会出现如下提示而无法继续. Can't locate Win32/Console.pm in @INC (you may ...

  4. vulnhub:easy_cloudantivirus靶机

    kali:192.168.111.111 靶机:192.168.111.177 信息收集 端口扫描 nmap -A -v -sV -T5 -p- --script=http-enum 192.168. ...

  5. ABAP 物料主数据 屏幕增强按钮

    首先看效果,目标是在物料主数据中 基础数据页面新增一个按钮来满足跳转需求,这里以跳转百度为例 页面效果如下: 创建定制程序 事务代码 SPRO,路径:后勤-常规 -> 物料主数据 -> 配 ...

  6. iis express添加网站,并启动

    1.查看网站列表 C:\Program Files (x86)\Microsoft Visual Studio 12.0>"C:\Program Files\IIS Express\a ...

  7. File、Files、Path、Paths

    一.Path.Paths 和 File.Files // Paths 工具类,用于获取 Path 实例 Path path = Paths.get("files/Data.txt" ...

  8. 清华大学资源库 和 CocoaPods / Specs 等多个 资源库共存

    1.如果本地pod 索引文件库只有清华大学的资源库[https://mirrors.tuna.tsinghua.edu.cn/git/CocoaPods/Specs.git].如果新在github上制 ...

  9. jmeter中返回值提取并存储。

    jmeter中,关于对接口提取值如何存入CSV文件并且做到换列操作的处理.我这里简单介绍一下. 1.首先把接口调通(这个是必须条件),确认好需要提取存入csv的字段,这里以统计token跟userid ...

  10. cadence报错:Class must be one of IC, IO, DISCRETE, MECHANICAL, PLATING_BAR or DRIVER_CELL.

    在原理图文件上右键选择Edit Object Properties, 然后在class一栏中修改class为IC, IO, DISCRETE, MECHANICAL, PLATING_BAR or D ...