当前位置:网站首页>TCP Socket与TCP 连接
TCP Socket与TCP 连接
2022-06-30 15:47:00 【土豆西瓜大芝麻】
一. TCP Socket和TCP连接
- tcp socket
tcp socket 是标示了一台主机的进程,是tcp连接中一端的实例。socket不是连接,只是表示了其中一端。由IP和port构成。 - tcp 连接
tcp连接由两台主机上的进程的socket连接构成。
1.1 tcp 服务端
为建立tcp连接,扮演server角色的一端进程需要:
- 通过
socket()
系统调用新建一个socket(只是它本地创建一个tcp scoket,并不能构成一个连接);
sockfd = socket(AF_INET, SOCK_STREAM, 0);//只是创建本地的一个socket实体,得到一个fd,但并没有和任何端口以及IP 绑定;
///* address family, AF_xxx,协议簇,这里使用的是INET地址族,它是通过 TCP/IP 协议支持的 Internet 地址族*/
//SOCK_STREAM 说的是BSD 套接字类型是流(Stream),这种套接字提供了可靠的双向顺序数据流,可保证数据不会在传输过程中丢失、破坏或重复出现。流套接字通过 INET 地址族的 TCP 协议实现。
//http://www.javashuo.com/article/p-cftecbee-te.html
- 给新建的socket绑定IP和port。
bind(sockfd, (struct sockaddr *) &serv_addr, sizeof(serv_addr));
//将前面创建的socket实体(由sockfd表征),与IP:port绑定。绑定好的socket才能在后面使用。
其中serv_addr结构体内包含了IP和port信息。
- 通过
listen()
系统调用监听连接
listen(sockfd,5);//服务端开始监听,最多能与5个客户端建立tcp连接。
//int listen(int sockfd, int backlog);
//第二个参数backlog为建立好连接处于ESTABLISHED状态的队列的长度。backlog的最大值128(linux原文描述如下):If the backlog argument is greater than the value in /proc/sys/net/core/somaxconn, then it is silently truncated to that value; the default value in this file is 128. In kernels before 2.4.25, this limit was a hard coded value, SOMAXCONN, with the value 128.
//https://blog.csdn.net/u022812849/article/details/109737020
- 通过
accept()
系统调用接收连接
newsockfd = accept(sockfd, (struct sockaddr *) &cli_addr, &clilen)
这里newsockfd是通过accept()
系统调用新建的socket文件描述符。当server监听到连接请求,便用这个新生产的socket与远程client的socket通讯。
server.c核心代码(多进程版,每个进程处理一个client的连接)
while (1) {
newsockfd = accept(sockfd,
(struct sockaddr *) &cli_addr, &clilen);//从accept队列中取出一个已经建立的tcp连接
if (newsockfd < 0)
error("ERROR on accept");
pid = fork(); // 子进程处理连接
if (pid < 0)
error("ERROR on fork");
if (pid == 0) {
close(sockfd);
dostuff(newsockfd);
exit(0);
}
else close(newsockfd);
}
server.c
是一个多进程版本的tcp server,当有新的请求时,使用fork()
系统调用产生新进程来处理连接请求:
其实也可以用多线程来处理请求,当有新的请求时,使用pthread_create()
调用,产生新线程。详细代码参考 这里。
其实最有效当处理多请求当手段是使用系统epoll
,通过事件通知机制,non-blocking地处理请求。详细代码参考这里
1.2 Tcp 客户端
为了建立tcp连接,tcp client 做了下面这些事儿:
- 新建socket
sockfd = socket(AF_INET, SOCK_STREAM, 0);
- 通过系统调用connect(),与远程server监听socket发起连接请求。
connect(sockfd,&serv_addr,sizeof(serv_addr))
- 连接成功后,便可通过向新建的socket中read()和write()来实现通讯了。
n = write(sockfd,buffer,strlen(buffer));
n = read(sockfd,buffer,255);
二. socket 文件
在一切皆文件的Unix-like系统中,进程生产的socket通过socket文件来表示,进程通过向socket文件读写内容实现消息的传递。
在Linux系统中,通常socket文件在/proc/pid/fd文件下。通过上面的server.c和client.c实践一下,窥探一下对应的socket文件。
先编译server.c和client.c
gcc server.c -o server
gcc client.c -o client
运行在本地30000端口上:
server 30000
用lsof或者netstat查看server进程ID
根据pid(17009),去目录/proc/17009/fd下查看:
其中socket:[1293853508]便是socket文件。
运行client,连接到server上。
client localhost 30000
先不要发送消息,保持连接。然后通过 lsof命令查看30000端口:
看图中NAME这一列,其中
- 第一行,*:30000是server到监听socket文件名
- 第二行,localhost:57684->localhost:30000 (ESTABLISHED)是client端端socket文件名
- 第三行,localhost:30000->localhost:57684 (ESTABLISHED)是server 端为client端的请求建立的新的socket,负责和client通信
三. Unix Domain socket
上述所说的socket是internet domain socket,用于不同主机之间进程的通信。在Unix中,本机之间进程通信通常用另外一种socket( Unix domain socket)。新建Unix domain socket 连接和 internet domain socket 连接几乎上差不多,唯一的区别就是socket()系统调用时传入socket type 不同而已。
sockfd = socket(AF_UNIX,SOCK_STREAM,0)
注意这里的 AF_UNIX 和 上面的AF_INET 区别。
Unix socket server程序userver.c
Unix socket client程序uclient.c
编译:
gcc userver.c -o userver
gcc uclientj.c -o uclient
userver 接收一个参数,用于创建socket文件,参数便是socket文件的名字。比如用 /tmp/usfd作为socket文件。
userver /tmp/usfd
查看一下新生产的socket文件:
ls -l /tmp/usfd
该文件的mode string的第一个字符s表示这是一个socket文件。
原文链接:https://blog.csdn.net/bdss58/article/details/77929685
边栏推荐
- 深入分析GadgetInspector核心代码
- Interesting research on mouse pointer interaction
- Under the pressure of technology, you can quickly get started with eth smart contract development, which will take you into the ETH world
- Mathematical modeling for war preparation 35 time series prediction model
- Bc1.2 PD protocol
- 腾讯二面:@Bean 与 @Component 用在同一个类上,会怎么样?
- 为了使远程工作不受影响,我写了一个内部的聊天室 | 社区征文
- CloudXR如何推动XR的未来发展
- Halcon knowledge: matrix topic [02]
- There are so many kinds of coupons. First distinguish them clearly and then collect the wool!
猜你喜欢
Go zero micro Service Practice Series (VIII. How to handle tens of thousands of order requests per second)
牛客网:有多少个不同的二叉搜索树
[bjdctf2020]the mystery of ip|[ciscn2019 southeast China division]web11|ssti injection
荣盛生物冲刺科创板:拟募资12.5亿 年营收2.6亿
Halcon knowledge: regional topics [07]
【牛客网刷题系列 之 Verilog快速入门】~ 位拆分与运算
RT thread heap size setting
I implement "stack" with C I
MySQL transaction / lock / log summary
RT-Thread 堆區大小設置
随机推荐
Bidding announcement: remote disaster recovery project of Shenzhen Finance Bureau database
19:00 p.m. tonight, knowledge empowerment phase 2 live broadcast - control panel interface design of openharmony smart home project
中航无人机科创板上市:市值385亿 拳头产品是翼龙无人机
Additional: (not written yet, don't look at ~ ~ ~) corsfilter filter;
RT-Thread 堆区大小设置
Niuke network: longest continuous subarray with positive product
mysql主从配置
边缘计算平台如何助力物联网发展
The image variables in the Halcon variable window are not displayed, and it is useless to restart the software and the computer
How to get the preferential activities for stock account opening? Is online account opening safe?
Bidding announcement: Tianjin housing provident fund management center database all-in-one machine and database software project (budget: 6.45 million)
There are so many kinds of coupons. First distinguish them clearly and then collect the wool!
Under the pressure of technology, you can quickly get started with eth smart contract development, which will take you into the ETH world
go-zero微服务实战系列(八、如何处理每秒上万次的下单请求)
What role does "low code" play in enterprise digital transformation?
MySQL8.0开启远程连接权限的方法步骤
AVIC UAV technology innovation board is listed: the fist product with a market value of 38.5 billion is pterodactyl UAV
Table responsive layout tips for super nice
牛客网:最小花费爬楼梯
RT thread heap size setting