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. csr_matrix与ndarray类型互转

    ndarry 转 csr_matrix>>> import numpy as np>>> import scipy.sparse >>> my_m ...

  2. Linux 常用监控指标总结

    1. Linux运维基础采集项 做运维,不怕出问题,怕的是出了问题,抓不到现场,两眼摸黑.所以,依靠强大的监控系统,收集尽可能多的指标,意义重大.但哪些指标才是有意义的呢,本着从实践中来的思想,各位工 ...

  3. Finance财务软件(辅助核算专题)

    支持辅助核算和数量核算

  4. miscmisc --攻防世界

    题目: (1)解压后将图片放入16进制编辑器,搜索字符串flag发现 图片应该还包含其他文件 (2)使用foremost进行分离,得到压缩包,打开压缩包又有一张图片 (3) 图片同样使用编辑器查看,也 ...

  5. 完全使用vscode开发python

    完全使用vscode开发python 作为Python开发,以前一直使用Pycharm社区版,因为卡顿,尝试使用vscode替换,尝试后并在工作中使用了半个月觉得真香,所以分享给大家. 更详细的视频介 ...

  6. 几款Android 应用自动化测试工具

    本文转自:https://blog.csdn.net/hebbely/article/details/78901466 简述: 本文介绍几款流行的 Android应用自动化测试工具. Monkey测试 ...

  7. pytorch学习笔记(8)--搭建简单的神经网络以及Sequential的使用

    1.神经网络图 输入图像是3通道的32×32的,先后经过卷积层(5×5的卷积核).最大池化层(2×2的池化核).卷积层(5×5的卷积核).最大池化层(2×2的池化核).卷积层(5×5的卷积核).最大池 ...

  8. 前端将JSON数据格式化显示

    很简单 1 formatJsonData(jsonData) { 2 var smapleDetailData = JSON.stringify(JSON.parse(jsonData), null, ...

  9. jeecg 导出加批注

    public static void main(String[] args) throws IOException { // 创建工作簿对象 XSSFWorkbook wb = new XSSFWor ...

  10. wpBullet-20190604

    WordPress Plugins/Themes 和 PHP 的静态代码分析工具 Usage: wpbullet.py [-h] [--path PATH] [--enabled ENABLED] [ ...