套接字小结

本文详细介绍了Socket通信的基本概念、步骤及实现方式,并通过实例代码展示了如何使用Socket进行网络编程,包括套接字的创建、绑定、监听、接受连接以及通信过程。

Socket的详细介绍-优快云博客

步骤:

1、定义sockaddr_in结构体 并对里面的成员进行初始化

sin_family   IPV4还是IPV6

sin_port     端口号

hton: host to net  //主机 -> 网络   小端转大端

 struct sockaddr_in server_addr , client_addr;
    //对服务端网络信息结构体进行初始化
    server_addr.sin_family = AF_INET;
    server_addr.sin_port = htons(6060);
    //server_addr.sin_addr.s_addr = inet_addr("192.0.0.1");
    server_addr.sin_addr.s_addr = inet_addr("本地主机IPV4地址");
—

2、创建套接字  


    //创建套接字,该套接字起到监听与传输信息的作用
    int server_sockfd = socket(AF_INET , SOCK_STREAM , 0);

3、将 socket 绑定在指定的 IP 地址和端口


    //4.将IP地址与端口号绑定到监听套接字上
  bind(server_sockfd , (struct sockaddr*)&server_addr , sizeof(server_addr));

4、监听

等待连接

128代表监听序列的大小

listen(server_sockfd , 128);

5、接受连接

接收客户端的连接,第二个参数客户端的网络结构体,accept成功后可以通过第二个参数,获取客户端的ip

accept(server_sockfd , (struct sockaddr*)&client_addr , &addrlen))

Socket通信主要是为了解决计算机网络中的进程间通信问题。在网络编程中,有两个进程需要进行通信才能完成特定的任务,这两个进程可能运行在不同的计算机上,也可能运行在同一台计算机上的不同进程中。Socket提供了一种标准化的接口,使得这些进程能够在网络中进行数据交换和通信。

Socket也提供了一条可靠的通信通道,使得两个计算机之间可以进行数据交换和通信。就像我们在打电话或发送信息时需要先建立连接、传输数据,然后再断开连接一样,Socket也需要先建立连接、传输数据,最后再关闭连接。而且就像电话线路或电线路可以支持不同的通信协议和数据类型一样,Socket也可以支持不同的网络协议和数据格式。

#include <arpe/inet.h>
int inet_pton(int family, const char *strptr, void *addrptr);     //将点分十进制的ip地址转化为用于网络传输的数值格式
        返回值:若成功则为1,若输入不是有效的表达式则为0,若出错则为-1
 
const char * inet_ntop(int family, const void *addrptr, char *strptr, size_t len);     //将数值格式转化为点分十进制的ip地址格式
        返回值:若成功则为指向结构的指针,若出错则为NULL
#include<sys/socket.h>
#include<arpa/inet.h>
#include<netdb.h>
#include<stdio.h>
#include<unistd.h>
#include<stdlib.h>
#include<ctype.h>
#include<string.h>

#define _SERVER_IP "192.168.3.239"
int server_shutdown;

int main(void)
{
        struct sockaddr_in server_addr,client_addr;
        int server_sock,client_sock;
        char recv_buf[1500];
        char cip[16];
        int recv_len;
        int flag;
        socklen_t addrlen;
        server_shutdown = 1;
        /*定义网络信息结构体*/
        bzero(&server_addr,sizeof(server_addr));
        server_addr.sin_family = AF_INET;
        server_addr.sin_port = htons(8080);
        inet_pton(AF_INET,_SERVER_IP,&server_addr.sin_addr.s_addr);

        /*创建 sockfd*/
        if((server_sock = socket(AF_INET,SOCK_STREAM,0))==-1){
                perror("sock call failed");
                exit(0);
        }

        /*绑定网络信息*/
        if((bind(server_sock,(struct sockaddr*)&server_addr,sizeof(server_addr)))==-1){
                perror("bind call failed");
                exit(0);
        }
        /*网络连接监听*/
        listen(server_sock,128);
        while(server_shutdown){
                /*持续等待建立连接*/
                addrlen = sizeof(client_addr);
                if((client_sock = accept(server_sock,(struct sockaddr*)&client_addr,&addrlen))>0){
                /*客户端连接成功,向客户端返回欢迎信息*/
                bzero(recv_buf,sizeof(recv_buf));
                inet_ntop(AF_INET,&client_addr.sin_addr.s_addr,cip,16);
                sprintf(recv_buf,"Hi,%s\n",cip);
                send(client_sock,recv_buf,strlen(recv_buf),0);
                printf("connet success,ip %s , port %d\n",cip,ntohs(client_addr.sin_port));
                }else if(client_sock == -1){
                        perror("accept call failed");
                        exit(0);
                }
        }
        bzero(recv_buf,sizeof(recv_buf));
        while((recv_len = recv(client_sock,recv_buf,sizeof(recv_buf),0))>0){
                flag = 0;
                while(recv_len > flag){
                        recv_buf[flag]=toupper(recv_buf[flag]);
                        flag++;
                }
                send(client_sock,recv_buf,strlen(recv_buf),0);
                bzero(recv_buf,sizeof(recv_buf));
        }
}

#include<sys/socket.h>
#include<arpa/inet.h>
#include<netdb.h>
#include<stdio.h>
#include<unistd.h>
#include<stdlib.h>
#include<ctype.h>
#include<string.h>

#define _SERVER_IP "192.168.3.239"


int main(void)
{
        struct sockaddr_in server_addr;
        int client_sock;
        char recv_buf[1500];
        int recv_len;

        /*定义网络信息结构体*/
        bzero(&server_addr,sizeof(server_addr));
        server_addr.sin_family = AF_INET;
        server_addr.sin_port = htons(8080);
        inet_pton(AF_INET,_SERVER_IP,&server_addr.sin_addr.s_addr);

        /*创建 sockfd*/
        if((client_sock = socket(AF_INET,SOCK_STREAM,0))==-1){
                perror("sock call failed");
                exit(0);
        }

        /*发送一次连接请求*/
        if((connect(client_sock,(struct sockaddr*)&server_addr,sizeof(server_addr)))==-1){
                perror("bind call failed");
                exit(0);
        }

        recv(client_sock,recv_buf,sizeof(recv_buf),0);
        printf("%s",recv_buf);
        bzero(recv_buf,sizeof(recv_buf));

        while((fgets(recv_buf,sizeof(recv_buf),stdin))!=NULL){
                send(client_sock,recv_buf,strlen(recv_buf),0);
                recv(client_sock,recv_buf,sizeof(recv_buf),0);
                printf("%s\n",recv_buf);
                bzero(recv_buf,sizeof(recv_buf));
        }
        close(client_sock);
        return 0;

}

socket的阻塞模式和非阻塞模式(send和recv函数在阻塞和非阻塞模式下的表现)_socket send 阻塞-优快云博客

网络编程:socket的阻塞模式和非阻塞模式_socket阻塞和非阻塞-优快云博客

 

 

epoll水平触发(Level Triggered)和边缘触发(Edge Triggered)详解_epoll水平和边缘触发-优快云博客 

### 原始套接字实验总结 原始套接字(Raw Socket)是一种特殊的网络接口,允许应用程序直接访问底层网络协议栈。通过使用原始套接字,可以捕获和发送未经过高层协议处理的数据包,这对于实现特定的网络工具非常有用。 #### 功能与特点 Winsock 原始套接字提供了对低层网络协议的控制能力,能够接收和发送自定义的 IP 数据报[^1]。其主要特点是支持 ICMP 协议的应用开发以及更灵活的数据传输方式。例如,在端口扫描场景下,可以通过构造特定的 TCP 或 UDP 数据包来探测目标主机的服务状态;而在流量统计方面,则可利用捕获到的数据流分析通信模式并提取关键指标[^2]。 #### 编程方法概述 创建一个基于 Winsock 的原始套接字通常涉及以下几个核心操作: - 初始化 Winsock 库环境; - 调用 `socket()` 函数指定地址族、类型及协议号为 IPPROTO_RAW 创建 socket 对象; - 设置必要的选项如 SO_RCVBUF 和 IP_HDRINCL 来优化性能或指示操作系统不自动添加标准 IPv4 头部信息; - 使用 bind() 绑定本地地址以便限定监听范围; - 发送数据前需手动构建完整的IP头部连同有效载荷一起传递给 sendto() 方法执行远程投递动作; - 接收来自任意源节点的信息则依赖 recvfrom() 完成异步读取过程。 以下是简单的 Python 示例展示如何设置一个用于接收所有传入ICMP回显应答消息类型的程序片段: ```python import socket # 创建 raw socket, bin to all interfaces rawSocket = socket.socket(socket.AF_INET, socket.SOCK_RAW, socket.IPPROTO_ICMP) while True: packet = rawSocket.recvfrom(65565) print(packet) ``` 此脚本将持续打印出任何到达系统的 ICMP 数据包详情。 #### ICMP 协议解析 Internet 控制消息协议(ICMP)主要用于在 IP 层上提供错误报告和其他反馈机制。当尝试连接不存在的目标服务时,服务器会返回不可达通知;路由器也可能因超时等原因中断路径上的某些分组传送行为并向发起方汇报具体情况。上述现象均借助于不同种类编码形式下的 ICMP 报文得以体现出来。 ---
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值