Loading [MathJax]/jax/input/TeX/config.js
首页
学习
活动
专区
圈层
工具
发布
首页
学习
活动
专区
圈层
工具
MCP广场
社区首页 >专栏 >1-UNIX网络编程-Socket套接字编程简介

1-UNIX网络编程-Socket套接字编程简介

作者头像
zoujunjie202
发布于 2022-07-27 07:41:08
发布于 2022-07-27 07:41:08
1.3K00
代码可运行
举报
文章被收录于专栏:zoujunjie202zoujunjie202
运行总次数:0
代码可运行

触发学习UNIX网络编程的动力在于前段时间需要开发一个接入服务,需要考虑比较高的并发处理能力,且尽量少占用的机器资源,选用了JAVA的Netty框架,学习过程产生不少疑问,限于基础知识太薄弱无法理解原理,所以开始关注UNIX编程。

学习资料是这本书,书有砖头那么大,知识点非常多,分几个小章节记录汇总。这个章节作为开篇,记录最基础的API使用指引。

有C语言基础都可以看得懂的Server和Client端代

Server端代码

代码语言:javascript
代码运行次数:0
运行
AI代码解释
复制
#include <stdio.h>
#include <netinet/in.h>
#include <sys/socket.h>
#include <stdlib.h>
#include <string.h>
#include <unistd.h>
#include <errno.h>

#define MAXLINE     4096
#define LISTENQ     1024

int main(int argc , char **argv ){
    int                 listenfd, connfd, n;
    char                buff[MAXLINE+1];
    struct sockaddr_in  servaddr;
    // socket
    listenfd = socket(AF_INET, SOCK_STREAM, 0);
    bzero(&servaddr,sizeof(servaddr));
    servaddr.sin_family = AF_INET;
    servaddr.sin_addr.s_addr = htonl(INADDR_ANY);
    servaddr.sin_port = htons(13);
    // bind
    bind(listenfd, (struct sockaddr *)&servaddr, sizeof(servaddr));
    // listen
    listen(listenfd,LISTENQ);
    for(;;){
        connfd = accept(listenfd,NULL,NULL);
        while( ( n= read(connfd,buff,MAXLINE)) > 0 ){
            printf("receive message from client. message = %s",buff);
            write(connfd,buff,strlen(buff));
            bzero(&buff,sizeof(buff));
        }
        close(connfd);
    }
}

Client端代码

代码语言:javascript
代码运行次数:0
运行
AI代码解释
复制
#include <stdio.h>
#include <netinet/in.h>
#include <sys/socket.h>
#include <stdlib.h>
#include <string.h>
#include <unistd.h>

#define MAXLINE     4096
#define LISTENQ     1024

int
main(int argc , char **argv ){
    int                 sockfd, n;
    char                sendline[MAXLINE+1] ,recvline[MAXLINE+1];
    struct sockaddr_in  servaddr;
    // socket
    sockfd = socket(AF_INET, SOCK_STREAM, 0);
    bzero(&servaddr,sizeof(servaddr));
    servaddr.sin_family = AF_INET;
    servaddr.sin_port = htons(13);
    inet_pton(AF_INET,"127.0.0.1",&servaddr.sin_addr);
    // connect
    connect(sockfd, (struct sockaddr *)&servaddr, sizeof(servaddr));
    
    while( fgets(sendline,MAXLINE,stdin) != NULL ){
        write(sockfd,sendline,strlen(sendline));
        bzero(&recvline,sizeof(recvline));
        if( (n = read(sockfd,recvline,MAXLINE) ) > 0 ){
            recvline[n] = 0 ;
            printf("receive message from server. message = %s",recvline);
            // fputs(recvline,stdout);
        }
        bzero(&sendline,sizeof(sendline));
    }
    close(sockfd);
    exit(0);
}

程序运行示例

这是一个简单的回射程序,不管客户端发送什么消息,服务器端接受到消息之后原样返回给客户端。不包含任何错误判断和错误处理。

关键函数注解

代码语言:javascript
代码运行次数:0
运行
AI代码解释
复制
1、socket函数
int socket( int family , int type , int protocol );
    创建一个套接字文件,返回套接字文件描述符
[family]
    指定协议簇 : AF_INET(IPv4) AF_INET6(IPv6) 
    AF_LOCALUNIX协议) AF_ROUTE(路由套接字) AF_KEY(秘钥套接字)
[type]
    指定套接字类型 : SOCK_STREAM(字节流套接字)SOCK_DGRAM(数据报套接字)SOCK_SEQPACKET(有序分组套接字)ROCK_RAW(原始套接字)
[protocol]
     指定协议类型:IPPROTO_TCP(TCP传输协议)IPPROTO_UDP(UDP传输协议)IPPROTO_SCTP(STCP传输协议),
     设置为0可以表示选择给定family和type组合的系统默认值。通常设置为0
代码语言:javascript
代码运行次数:0
运行
AI代码解释
复制
2、bind函数
int bind(int sockfd , const struct sockaddr *myaddr , 
socklen_t addrlen);
    把一个本地协议地址赋予一个套接字
[sockfd]
    socket函数返回的套接字描述符
[myaddr]
    是指向本地IP地址的通用套接字结构
[addrlen]
    特定套接字结构的长度(IPv4、IPv6、Unix域、数据链路、存储等)
代码语言:javascript
代码运行次数:0
运行
AI代码解释
复制
3、listen函数
int listen( int sockfd , int backlog );
    把一个本地协议地址赋予一个套接字,把套件字变更为被动连接。
[sockfd]
    socket指示内核接受指向该套接字的连接请求。
[backlog]
    未完成三次握手的请求 + 已完成三次握手的请求总和。是一个大约值。
代码语言:javascript
代码运行次数:0
运行
AI代码解释
复制
4、accept函数
int accept( int sockfd , struct sockaddr *cliaddr , 
scoklen_t *addrlen );
    从已完成连接队列队头返回下一个已完成连接,如果丢列为空,
    进程阻塞进入睡眠。
[sockfd]
    socket等待接受连接的侦听套接字。
[cliaddr]
    客户端协议地址。如果不关注客户端的地址,可以设置为NULL[addrlen]
    客户端协议地址的端口号。如果不关注,可以设置为NULL
代码语言:javascript
代码运行次数:0
运行
AI代码解释
复制
5、connect函数
int connect( int sockfd , const struct sockaddr * servaddr , 
socklen_t addrlen );
     TCP客户端发起跟服务器的连接。
[sockfd]
    由socket函数创建的套接字连接
[servaddr]
    包含服务器IP地址和端口号的套接字地址结构
[addrlen]
     套接字地址结构的大小。
代码语言:javascript
代码运行次数:0
运行
AI代码解释
复制
bzero       字节操纵函数,用于把目的结构体中指定数目的字节置为0
            类似于memset函数,但是比memset少一个容易出BUG的参数
            在C语言里,对一块刚申请的内存先清零再使用是必须的
htonl\htons 字节排序函数,
            htonl是对32位的IPv4地址做转换
            htons是对16为的端口号做转换
            由机器字节序转变为网络字节序,网际协议使用大端字节序来表示
            字符,而机器则是不同操作系统使用不同的字节序
read        从连接套接字中读取指定长度的内容
write       往连接套接字中写取指定长度的内容
inet_pton   把字符串格式的IP地址,转成相应协议族的数值格式
            另外一个配套的函数是inet_ntop,作用相反
fgets       函数,从标准输入中读取指定长度字符串,有点像scanf

基础知识补齐

1、Socket在OSI(开放系统互联)模型——7层网络模型中的位置

Socket就像一个插头,联通应用层中的应用与网络设备,应用要提供网络服务,或者需要网络服务都得通过Socket的API进行。

2、Socket API的数据流

下周文章提纲

1、C语言错误处理

2、项目文件组织与编写Makefile

3、完成server和client中其他函数的包裹

本文参与 腾讯云自媒体同步曝光计划,分享自微信公众号。
原始发表:2019-07-27,如有侵权请联系 cloudcommunity@tencent.com 删除

本文分享自 zoujunjie202 微信公众号,前往查看

如有侵权,请联系 cloudcommunity@tencent.com 删除。

本文参与 腾讯云自媒体同步曝光计划  ,欢迎热爱写作的你一起参与!

评论
登录后参与评论
暂无评论
推荐阅读
编辑精选文章
换一批
网络编程入门_回显服务器
sockaddr和sockaddr_in包含的数据都是一样的,但他们在使用上有区别: 程序员不应操作sockaddr,sockaddr是给操作系统用的 程序员应使用sockaddr_in来表示地址,sockaddr_in区分了地址和端口,使用更方便。 一般的用法为: 程序员把类型、ip地址、端口填充sockaddr_in结构体,然后强制转换成sockaddr,作为参数传递给系统调用函数
yifei_
2022/11/14
7530
网络编程入门_回显服务器
UDP套接口编程
常用的UDP实现的程序:DNS域名系统,NFS网络文件系统,SNMP简单网络管理协议 ssize_t recvfrom(int sockfd,void *buff,size_t nbytes,int flags,struct sockaddr * from,socklen_t *addrlen); ssize_t sendto(int sockfd,void *buff,size_t nbytes,int flags,struct sockaddr * to,socklen_t addrlen); sock
用户1154259
2018/01/17
1K0
2-UNIX网络编程-进阶学习前的基础知识储备
诚实点,并不是假设读的人C语言基础很差,而事实是,自己的C语言基础实在太差,要补学基础知识之后才可以进行后续的学习,惭愧!
zoujunjie202
2022/07/27
4480
2-UNIX网络编程-进阶学习前的基础知识储备
简单的客户机服务器投射模拟
下面模拟了,简单的客户机服务器投射模拟的过程。客户机像服务器发送数据,服务器接受到数据后,发送回给客户机。再由客户机打印出来。 需要的函数: 网络方面 服务器 socket(AF_INET,SOCK_STREAM,0);  AF_INET表示IPV4,SOCK_STREAM表示基于字节流的,0表示协议由前面两个参数组合而成。返回描述符 bind(sockdf,(struct sockaddr*)servaddr,sizeof(servaddr));   用于把描述符与本地协议地址联系起来。 listen
用户1154259
2018/01/17
1K0
UNIX网络编程卷1(第三版)基本TCP套接字编程
其中family参数指明协议族,type参数指明套接字类型,proctocol参数为协议类型或者0
心跳包
2020/08/31
6450
SOCKET网络编程 (通俗易懂入门篇)
struct sockaddr :很多网络编程函数的出现早于IPV4协议,为了向前兼容,现在sockaddr都退化成(void *)结构了。 传递一个地址给函数,然后由函数内部再强制类型转换为所需的地址类型。
看、未来
2020/08/25
1.2K0
SOCKET网络编程 (通俗易懂入门篇)
UNIX网络编程卷1(第三版) 客户/服务器程序示例
创建TCP套接字。在待绑定到该套接字的网际网套接字地址结构中填入通配地址(INADDR_ANY)和服务器众所周知的端口(SERV_PORT).捆绑通配地址是告诉系统:要是系统是多宿主机,我们将接受目的地址为任何本地接口的连接。listen把该套接字转成一个监听套接字。
心跳包
2020/08/31
4670
select()函数详解
http://www.cnblogs.com/Anker/archive/2013/08/14/3258674.html
bear_fish
2018/09/20
1.9K0
select()函数详解
如何对回显服务器进行改进_1
上一篇中写了一个基本的回显服务器,最基本的功能是有了,但是并不够健壮,那么如何对它进行改进呢?我们需要考虑以下几种情况。
yifei_
2022/11/14
7130
2021版!万字UNIX网络编程学习笔记(套接字篇)
#2.直接编译 gcc -o 1.out daytimetcpcli.c #错误提示如下: daytimetcpcli.c:1:17: fatal error: unp.h: No such file or directory #include "unp.h" ^ compilation terminated. #在../key目录下找到unp.h。继续提醒没有<sys/fiflo.h>从网上下载继续出问题。
心跳包
2021/09/26
1.1K0
2021版!万字UNIX网络编程学习笔记(套接字篇)
UNIX(进程间通信):17 深入理解unix域
unix域协议并不是一个实际的协议族,而是在单个主机上执行客户/服务器通信的一种方法。
用户3479834
2021/03/04
1.9K0
UNIX(进程间通信):17 深入理解unix域
poll()函数总结
http://www.cnblogs.com/Anker/archive/2013/08/15/3261006.html
bear_fish
2018/09/20
2.4K0
poll()函数总结
linux下Socket编程(一)简介
socket起源于Unix,而Unix/Linux基本哲学之一就是“一切皆文件”,都可以用“打开open –> 读写write/read –> 关闭close”模式来操作。Socket就是该模式的一个实现, socket即是一种特殊的文件,一些socket函数就是对其进行的操作(读/写IO、打开、关闭)。 说白了Socket是应用层与TCP/IP协议族通信的中间软件抽象层,它是一组接口。在设计模式中,Socket其实就是一个门面模式,它把复杂的TCP/IP协议族隐藏在Socket接口后面,对用户来说,一组简单的接口就是全部,让Socket去组织数据,以符合指定的协议。 注意: 其实socket也没有层的概念,它只是一个facade设计模式的应用,让编程变的更简单。是一个软件抽象层。在网络编程中,我们大量用的都是通过socket实现的。
用户2929716
2018/08/23
3.8K0
linux下Socket编程(一)简介
Linux网络编程TCP
TCP/IP 协议栈是一系列网络协议(protocol)的总和,是构成网络通信的核心骨架,它定义了电子设备如何连入因特网,以及数据如何在它们之间进行传输。
DeROy
2021/11/16
5.9K0
Linux网络编程TCP
套接字函数 | socket、bind、listen、accept、connect
AF_INET 这是大多数用来产生socket的协议,使用TCP或UDP来传输,用IPv4的地址。
mindtechnist
2024/08/08
3540
套接字函数 | socket、bind、listen、accept、connect
【Socket】Socket相关概念及函数
Socket中文意思是"插座",在Linux环境下,用于表示进程间网络通信的特殊文件类型。本质为内核借助缓冲区形成的伪文件。
半生瓜的blog
2023/05/13
9540
【Socket】Socket相关概念及函数
【Linux/unix网络编程】之使用socket进行TCP编程
循环接收客户发来的信息并在终端上显示,同时在信息前加入序号并返回给客户端;当从客户接收到bye后不再发送给各户并退出程序。
马三小伙儿
2018/09/12
5860
Socket编程实践(2) Socket API 与 简单例程
在本篇文章中,先介绍一下Socket编程的一些API,然后利用这些API实现一个客户端-服务器模型的一个简单通信例程。该例子中,服务器接收到客户端的信息后,将信息重新发送给客户端。 socket()函数 socket()函数用于创建一个套接字。这就好像购买了一个电话。不过该电话还没有分配号码。 #include <sys/types.h> #include <sys/socket.h> int socket(int domain, int type, int protocol
Tencent JCoder
2018/07/02
9090
linux 下经典 IO 复用模型 -- epoll 的使用
epoll 是 linux 内核为处理大批量文件描述符而对 poll 进行的改进版本,是 linux 下多路复用 IO 接口 select/poll 的增强版本,显著提高了程序在大量并发连接中只有少量活跃的情况下的CPU利用率。 在获取事件时,它无需遍历整个被侦听描述符集,只要遍历被内核 IO 事件异步唤醒而加入 ready 队列的描述符集合就行了。 epoll 除了提供 select/poll 所提供的 IO 事件的电平触发,还提供了边沿触发,,这样做可以使得用户空间程序有可能缓存 IO 状态,减少 epoll_wait 或 epoll_pwait 的调用,提高程序效率。
用户3147702
2022/06/27
8050
linux 下经典 IO 复用模型 -- epoll 的使用
linux服务器开发三(网络编程) --二
半关闭 当TCP链接中A发送FIN请求关闭,B端回应ACK后(A端进入FIN_WAIT_2状态),B没有立即发送FIN给A时,A方处在半链接状态,此时A可以接收B发送的数据,但是A已不能再向B发送数据。 从程序的角度,可以使用API来控制实现半连接状态。 #include <sys/socket.h> int shutdown(int sockfd, int how); sockfd: 需要关闭的socket的描述符 how: 允许为shutdown操作选择以下几种方式: SHUT
李海彬
2018/03/27
2.5K0
linux服务器开发三(网络编程) --二
相关推荐
网络编程入门_回显服务器
更多 >
领券
问题归档专栏文章快讯文章归档关键词归档开发者手册归档开发者手册 Section 归档
本文部分代码块支持一键运行,欢迎体验
本文部分代码块支持一键运行,欢迎体验