socket编程代码示例

news2024/12/26 21:10:12

1. TCP server client模拟聊天对话框

server.c

/* server.c */
#include <stdio.h>
#include <stdlib.h>
#include <string.h>
#include <strings.h>
#include <errno.h>
#include <unistd.h>
#include <sys/types.h>
#include <sys/socket.h>
#include <netinet/in.h>
#include <arpa/inet.h>

#define BUFFER_SIZE (1024)
#define IP_SIZE (100)
#define SERVER_SUCCESS (0)
#define SERVER_FAILURE (-1)
#define MAX_PENDDING_QUEUE (10)

typedef enum {
    false = 0,
    true = 1,
} bool;

static void server_usage(void)
{
    printf("#####################################\n");
    printf("#Server Usage:                      #\n");
    printf("#gcc server.c -o server             #\n");
    printf("#chmod 777 server                   #\n");
    printf("#./server <ip> <port>               #\n");
    printf("#                                   #\n");
    printf("#<ip>:server ip:192.168.xx.xx       #\n");
    printf("#<port>:server port:1024~65535      #\n");
    printf("#####################################\n");
    return;
}

int main(int argc, char *argv[])
{
    int listenfd = -1;
    int connectfd = -1;
    int ret;
    int recv_bytes;

    struct sockaddr_in serveraddr;
    struct sockaddr_in clientaddr;

    socklen_t peerlen;

    char server_buf[BUFFER_SIZE] = {0};
    char client_addr[IP_SIZE] = {0};

    if (argc < 3) {
        server_usage();
        return SERVER_FAILURE;
    }

    /* socket */
    listenfd = socket(AF_INET, SOCK_STREAM, 0);
    if (listenfd == -1) {
        printf("[ERROR]server socket failed, why:%s\n", strerror(errno));
        return SERVER_FAILURE;
    }
    printf("[DEBUG]server socket success, listenfd = %d\n", listenfd);

    /* serveraddr */
    memset(&serveraddr, 0x00, sizeof(serveraddr));
    serveraddr.sin_family = AF_INET;
    serveraddr.sin_port = htons(atoi(argv[2]));
    inet_pton(AF_INET, argv[1], &serveraddr.sin_addr);

    /* bind */
    ret = bind(listenfd, (const struct sockaddr *)&serveraddr, sizeof(serveraddr));
    if (ret != 0) {
        printf("[ERROR]server bind failed, why:%s\n", strerror(errno));
        close(listenfd);
        return SERVER_FAILURE;
    }
    printf("[DEBUG]server bind success\n");

    /* listen */
    ret = listen(listenfd, MAX_PENDDING_QUEUE);
    if (ret != 0) {
        printf("[ERROR]server listen failed, why:%s\n", strerror(errno));
        close(listenfd);
        return SERVER_FAILURE;
    }
    printf("[DEBUG]server listen success\n");

    printf("server waiting for connect......\n\n");

    /* accept */
    while (true) {
        memset(&clientaddr, 0x00, sizeof(clientaddr));
        peerlen = sizeof(clientaddr);

        connectfd = accept(listenfd, (struct sockaddr *)&clientaddr, &peerlen);
        if (connectfd == -1) {
            printf("[ERROR]server accept failed, why:%s\n", strerror(errno));
            close(listenfd);
            return SERVER_FAILURE;
        }
        memset(client_addr, 0x00, sizeof(client_addr));
        inet_ntop(AF_INET, &clientaddr.sin_addr, client_addr, sizeof(client_addr));
        printf("[DEBUG]server connected, client ip:%s, port:%d\n\n", client_addr, ntohs(clientaddr.sin_port));

        /* send and recv */
        while (true) {

            memset(server_buf, 0x00, sizeof(server_buf));

            printf("\033[1m<--- \033[0m"), fflush(stdout);
            recv_bytes = recv(connectfd, server_buf, sizeof(server_buf), 0);
            if (recv_bytes == -1) {
                printf("[ERROR]server recv failed, why:%s\n", strerror(errno));
                close(connectfd);
                close(listenfd);
                return SERVER_FAILURE;
            } else if (recv_bytes == 0) {
                printf("[DEBUG]server detected client gone!\n");
                close(connectfd);
                break;
            }

            printf("client@%s:%d said:%s\n", inet_ntoa(clientaddr.sin_addr), ntohs(clientaddr.sin_port), server_buf);
            
            memset(server_buf, 0x00, sizeof(server_buf));
            printf("\033[1m---> \033[0m"), fflush(stdout);
            fgets(server_buf, sizeof(server_buf), stdin);
            send(connectfd, server_buf, sizeof(server_buf), 0);
            printf("\n");
        }
    }
    close(listenfd);
    return SERVER_SUCCESS;
}

client.c

/* client.c */
#include <stdio.h>
#include <stdlib.h>
#include <string.h>
#include <strings.h>
#include <errno.h>
#include <unistd.h>
#include <sys/types.h>
#include <sys/socket.h>
#include <netinet/in.h>
#include <arpa/inet.h>

#define BUFFER_SIZE (1024)
#define CLIENT_SUCCESS (0)
#define CLIENT_FAILURE (-1)
#define MAX_PENDDING_QUEUE (10)

typedef enum {
    false = 0,
    true = 1,
} bool;

static void client_usage(void)
{
    printf("#####################################\n");
    printf("#Client Usage:                      #\n");
    printf("#gcc client.c -o client             #\n");
    printf("#chmod 777 client                   #\n");
    printf("#./client <ip> <port>               #\n");
    printf("#                                   #\n");
    printf("#<ip>:server ip:192.168.xx.xx       #\n");
    printf("#<port>:server port:1024~65535      #\n");
    printf("#####################################\n");
    return;
}


int main(int argc, char *argv[])
{
    int sockfd = -1;
    int ret;
    int recv_bytes;
    struct sockaddr_in serveraddr;
    char client_buf[BUFFER_SIZE] = {0};

    if (argc < 3) {
        client_usage();
        return CLIENT_FAILURE;
    }

    /* socket */
    sockfd = socket(AF_INET, SOCK_STREAM, 0);
    if (sockfd == -1) {
        printf("[ERROR]client socket failed, why:%s\n", strerror(errno));
        return CLIENT_FAILURE;
    }
    printf("[DEBUG]client socket success, sockfd = %d\n", sockfd);

    /* serveraddr */
    memset(&serveraddr, 0x00, sizeof(serveraddr));
    serveraddr.sin_family = AF_INET;
    serveraddr.sin_port = htons(atoi(argv[2]));
    inet_pton(AF_INET, argv[1], &serveraddr.sin_addr);

    ret = connect(sockfd, (const struct sockaddr *)&serveraddr, sizeof(serveraddr));
    if (ret == -1) {
        printf("[ERROR]client connect failed, why:%s\n", strerror(errno));
        close(sockfd);
        return CLIENT_FAILURE;
    }
    printf("[DEBUG]client connect success\n");

    while (true) {

        memset(client_buf, 0x00, sizeof(client_buf));
        printf("\033[1m---> \033[0m"), fflush(stdout);
        fgets(client_buf, sizeof(client_buf), stdin);
        printf("\n");

        /* client said quit */
        if (strncmp(client_buf, "quit!", strlen("quit!")) == 0) {
            printf("[DEBUG]client said %s\n", client_buf);
            break;
        }

        send(sockfd, client_buf, sizeof(client_buf), 0);

        memset(client_buf, 0x00, sizeof(client_buf));

        printf("\033[1m<--- \033[0m"), fflush(stdout);
        recv_bytes = recv(sockfd, client_buf, sizeof(client_buf), 0);
        if (recv_bytes == -1) {
            printf("[ERROR]client recv failed, why:%s\n", strerror(errno));
            close(sockfd);
            return CLIENT_FAILURE;
        } else if(recv_bytes == 0) {
            printf("[DEBUG]client detected server gone!\n");
            break;
        }
        printf("server@%s:%d said:%s\n", argv[1], atoi(argv[2]), client_buf);
    }
    close(sockfd);
    printf("[DEBUG]<=====client exit\n");
    return CLIENT_SUCCESS;
}

wireshark抓包结果:

2. 用原始套接字模拟ping操作并解析IP包与ICMP包

//This is a ping which can both send and receive ICMP packets
#include <sys/types.h>
#include <unistd.h>
#include <errno.h>
#include <signal.h>
#include <sys/socket.h>
#include <netinet/in.h>
#include <arpa/inet.h>
#include <linux/tcp.h>
#include <netinet/ip_icmp.h>
#include <strings.h>
#include <stdio.h>
#include <stdlib.h>
#include <string.h>
#include <arpa/inet.h>

#define PING_SUCCESS (0)
#define PING_FAILURE (-1)
#define BUFFER_SIZE (1024)
#define MAGIC_NUM (3623)
//#define DEBUG

static unsigned short calc_cksum(unsigned short *addr, int len)
{
    int sum=0;
    unsigned short res=0;
    while( len > 1) {
        sum += *addr++;
        len -= 2;
    }

    if( len == 1) {
        *((unsigned char *)(&res))=*((unsigned char *)addr);
        sum += res;
    }

    sum = (sum >>16) + (sum & 0xffff);
    sum += (sum >>16) ;
    res = ~sum;
    return res;
}

int main(int argc, char *argv[])
{
    if (argc < 4) {
        printf("param error, usage: ./ping serverip -c <count>\n");
        return PING_FAILURE;
    }

    int count = atoi(argv[3]);
    char send_buff[BUFFER_SIZE] = {0};
    char recv_buff[BUFFER_SIZE] = {0};
    char src_buff[BUFFER_SIZE] = {0};

    int sockfd = -1;
    int recvfd = -1;
    int ret, i, lenfrom;

    struct sockaddr_in target_addr;
    struct sockaddr_in source_addr;

    /* socket */
    sockfd = socket(AF_INET, SOCK_RAW, IPPROTO_ICMP);
    if (sockfd == -1) {
        printf("sockfd create for IPPROTO_ICMP failed, why:%s\n", strerror(errno));
        return PING_FAILURE;
    }
    recvfd = socket(AF_INET, SOCK_RAW, IPPROTO_ICMP);
    if (recvfd == -1) {
        printf("recvfd create for IPPROTO_ICMP failed, why:%s\n", strerror(errno));
        close(sockfd);
        return PING_FAILURE;
    }

#ifdef DEBUG
    printf("[DEBUG]socket create for IPPROTO_ICMP success\n");
#endif

    memset(&target_addr, 0x00, sizeof(target_addr));
    ret = inet_pton(AF_INET, argv[1], &target_addr.sin_addr);
    if (ret != 1) {
        printf("bad ip address to be converted:%s\n", argv[1]);
        close(recvfd);
        close(sockfd);
        return PING_FAILURE;
    }

    struct icmp *picmp = (struct icmp *)send_buff;
    struct ip *pip = (struct ip*)recv_buff;
    struct icmp *p_recvicmp = (struct icmp *)(pip + 1);

    for (i = 0; i < count; i++) {
        memset(send_buff, 0x00, sizeof(send_buff));

        /*----TYPE----CODE----CHECKSUM----
         *----IDENTIFIER------SEQUENCE----
         *----OPTION----------------------
         */
        picmp->icmp_type = ICMP_ECHO; /* ECHO-REQUEST */
        picmp->icmp_code = 0;
        picmp->icmp_id = MAGIC_NUM;
        picmp->icmp_seq = i;
        picmp->icmp_cksum = calc_cksum((unsigned short *)picmp, 8);

        /* PING REQUEST */
        ret = sendto(sockfd, send_buff, 64, 0, (const struct sockaddr *)&target_addr, sizeof(target_addr)); /* ICMP total 64 bytes */
        if (ret == -1) {
            printf("turn %d sendto error, why:%s\n", i, strerror(errno));
            close(recvfd);
            close(sockfd);
            return PING_FAILURE;
        }

#ifdef DEBUG
        printf("[DEBUG]turn %d, %d bytes send...\n", i, ret);
#endif

        /* PING REPLY */
        memset(recv_buff, 0x00, sizeof(recv_buff));
        memset(&source_addr, 0x00, sizeof(source_addr));
        lenfrom = sizeof(source_addr);
        ret = recvfrom(sockfd, recv_buff, sizeof(recv_buff), 0, (struct sockaddr *)&source_addr, &lenfrom);
        if (ret == -1) {
            printf("turn %d recvfrom error, why:%s\n", i, strerror(errno));
            close(recvfd);
            close(sockfd);
            return PING_FAILURE;
        } else if (ret == 0) {
            printf("turn %d detect socket peer shutdown!\n", i);
            close(recvfd);
            close(sockfd);
            return PING_FAILURE;
        }

#ifdef DEBUG
        printf("[DEBUG]turn %d, %d bytes recv\n", i, ret);
        printf("[DEBUG]recv ip header len = %d\n", pip->ip_hl);
#endif

        if ((ret - (pip->ip_hl * 4)) < 8) { /* we assume ICMP at least 8 byte */
            printf("turn %d no ICMP reply!\n", i);
            close(recvfd);
            close(sockfd);
            return PING_FAILURE;
        }

        if ((p_recvicmp->icmp_type == ICMP_ECHOREPLY) && (p_recvicmp->icmp_id == MAGIC_NUM)) {
            /* get the src and dst addr */
            memset(src_buff, 0x00, sizeof(src_buff));

            /* from where? */
            inet_ntop(AF_INET, &source_addr.sin_addr, src_buff, sizeof(src_buff));

            printf("[myping]%d bytes from %s to %s: icmp_seq=%u ttl=%d\n", (ret-(pip->ip_hl * 4)), (src_buff), (inet_ntoa(pip->ip_dst)), (p_recvicmp->icmp_seq), (pip->ip_ttl));
        } else {
            printf("[myping]recv no wanted packet!\n");
            continue;
        }

    }

    printf("done!\n");
    close(recvfd);
    close(sockfd);
    return PING_SUCCESS;
}

 wireshark抓包结果:

 

本文来自互联网用户投稿,该文观点仅代表作者本人,不代表本站立场。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如若转载,请注明出处:http://www.coloradmin.cn/o/772200.html

如若内容造成侵权/违法违规/事实不符,请联系多彩编程网进行投诉反馈,一经查实,立即删除!

相关文章

jmeter使用PerfMon插件监测服务器资源时 连接超时

异常提示&#xff1a; ERROR: java.net.ConnectException: Connection timed out: connect 解决方案&#xff1a; 一种情况下是端口未启用&#xff1b; 另一种情况更新端口号&#xff0c;将默认端口进行修改 4444 修改为其他未使用的端口号&#xff08;例如&#xff1a;4445 &…

vue基础-axios详解

1.1 背景 Axios 是一个基于 promise 的 HTTP 库&#xff0c;可以用在浏览器和 node.js 中, 也是 vue 官方推荐使用的 http 库&#xff1b;封装axios&#xff0c;一方面为了以后维护方便&#xff0c;另一方面也可以对请求进行自定义处理。 1.2 vue请求模块选择 2 应用 2.1 安…

第八十八回:创建一个调色板

文章目录 概念介绍实现方法整体思路具体步骤 示例代码 我们在上一章回中介绍了打印日志相关的内容&#xff0c;本章回中将介绍 如何创建一个调色板.闲话休提&#xff0c;让我们一起Talk Flutter吧。 概念介绍 我们在本章回中介绍的调色板是一个具有各种颜色的窗口&#xff0c…

大口径均匀性大于98%积分球均匀光源

大口径宽视场光学成像遥感器的探测元件采用阵列探测器或多片阵列探测器拼接而成,由于阵列探测器像元间辐射响应差异和光学系统的非理想性&#xff0c;影响了光学成像遥感器的成像质量&#xff0c;进而影响测量的准确性&#xff0c;因此在有效应用前必须对大口径宽视场光学成像遥…

【hadoop】hadoop的体系架构

hadoop的体系架构 HDFS的体系架构NameNodeedits文件&#xff08;客户端的操作日志&#xff09;fsimage文件&#xff08;元信息文件&#xff09; DataNodeSecondary NameNode Yarn的体系架构HBase主从架构的单点故障的问题 HDFS的体系架构 NameNode NameNode&#xff1a;主节点…

idea-实现热部署

idea-实现热部署 今天在进行idea 开发时突然发现热部署失败了&#xff0c;每次修改内容都要去restart server一次 这样比较麻烦&#xff0c;故而总结一下idea实现热部署的方法&#xff1a; 步骤一&#xff1a; 选择edit configuration 然后跳出server 的配置&#xff0c;方框…

Go语言之并发编程练习

GO协程初识 package mainimport ("fmt""sync""time" )func read() {defer wg.Done()fmt.Println("read start")time.Sleep(time.Second * 3)fmt.Println("read end") }func listenMusci() {defer wg.Done()fmt.Println(&qu…

ENSP实验三:搭建VPN(GRE,未配置安全策略)

目录 1、基础配置&#xff1a;IP地址&#xff0b;防火墙安全区域&#xff1b; 2、使ISP&#xff08;运营商&#xff09;网络的路由可达-OSPF&#xff1b; 3、建立VPN隧道&#xff08;两个防火墙之间&#xff09;&#xff1b; 4、引流 1、基础配置&#xff1a;IP地址&#xf…

c语言小项目——通讯录中阶(动态内存版)

通讯录初阶&#xff1a;点这里 通讯录高阶&#xff1a;点这里 动态内存版改进之处结构体初始化通讯录添加联系人销毁通讯录 完整代码contact.hcontact.ctest.c 动态内存版改进之处 结构体 contact.c 初始化通讯录 contact.h contact.c 添加联系人 contact.c 销毁通讯录 te…

Linux挂载iso镜像文件为yum源

场景 工作中&#xff0c;经常需要在公司的内网环境节点安装一些第三方的服务&#xff08;例如HaProxy&#xff09;&#xff0c;一般他们都依赖一些基础工具&#xff0c;或者基础库&#xff0c;例如 openssl 、openssl-devel、gcc 等等。如果能联网&#xff0c;直接通过 yum 命…

干洗店预约下单小程序,洗衣店洗鞋店收银软件会员取衣管理

干洗店预约下单小程序&#xff0c;洗衣店洗鞋店收银软件会员取衣管理 干洗店洗鞋店同城预约上门洗衣系统小程序洗护软件APP码上洗鞋 主要功能&#xff1a; 1、专业的收衣收鞋功能。接收客户的预洗衣物&#xff0c;根据要求和提示输入衣物详细信息&#xff0c;包括衣服的颜色&a…

selenium-多窗口和frame处理

1.切换窗口 适用场景&#xff1a;点击按钮后&#xff0c;重新打开一个窗口&#xff0c;想要在新的窗口定位操作&#xff0c;就需要切换窗口 原理&#xff1a;获取窗口的唯一标识就是句柄&#xff0c;获取到句柄&#xff0c;就可以切换到对应的窗口了 处理方法&#xff1a; …

M7二极管-ASEMI迷你贴片整流二极管M7二极管

编辑&#xff1a;ll M7二极管-ASEMI迷你贴片整流二极管M7二极管 型号&#xff1a;M7二极管 品牌&#xff1a;ASEMI 芯片个数&#xff1a;1 芯片尺寸&#xff1a;46MIL 封装&#xff1a;SMAF 恢复时间&#xff1a;ns 工作温度&#xff1a;-50C~150C 浪涌电流&#xff1…

python实现拼多多商品详情接口API

最近工作需要用到拼多多的一些接口&#xff0c;官方竟然没有提供&#xff0c;python的sdk&#xff0c;于是就自己简单的写了一个商品SKU接口的api。 1、代码 #!/usr/bin/python3# -*- coding: utf-8 -*-# Time : 2020/3/29 0021 下午 19:40# Author : xiaozhi&#xff01;…

docker基础1——架构组成、安装配置

文章目录 一、发展起源1.1 传统虚拟化与容器虚拟化1.2 docker底层核心技术1.2.1 命名空间1.2.2 控制组 1.3 docker工作方式1.4 docker容器编排1.5 docker优劣势1.6 docker架构组成 二、yum安装docker三、配置docker加速器 一、发展起源 背景了解&#xff1a; 容器是内核里的一项…

重磅升级 | 睿士主机威胁溯源系统全新升级,助力用户2023网络攻防演练

攻防演练至今已走过7个年头&#xff0c;逐渐成为网络安全防御体系中至关重要的一环。随着攻防演练对抗水平不断升级&#xff0c;攻击手段愈发隐蔽&#xff0c;攻击自动化程度逐步提高&#xff0c;技术储备也越来越有针对性&#xff0c;从广撒网到精准打击&#xff0c;这些都给蓝…

解决find: ‘/run/user/1000/gvfs’: 权限不够

问题描述 在用find查找对应的文件时&#xff0c;突然报错这个问题 解决办法 其实这个目录是空的&#xff0c;所以删除就好了执行下列操作&#xff1a; umount /run/user/1000/gvfs rm -rf /run/user/1000/gvfs 之后的查找中就没有了报错提示。

Spring AOP的介绍与实现

文章目录 Spring AOP1. Spring AOP概念2. Spring AOP的作用3.AOP的组成4. Spring AOP的实现4.1 添加Spring AOP依赖4.2 定义切面&#xff08;创建切面类&#xff09;4.3 定义切点&#xff08;配置拦截规则&#xff09;4.3.1 切点表达式语法 4.4 定义通知的实现 5. Spring AOP实…

【Java】Mybatis使用Collection属性

前言 这篇文章实现一下不使用left join等连接关键字来实现Mybatis的联表查询功能。包括json类型数据映射到Java实体类中。 库表 父表db1_json 子表db1_json_attach&#xff0c;子表parent_id对应副本的id。 实体类 新建Db1JsonDTO数据传递对象实体。 Data public class Db…

GRE实验

题目参考&#xff1a; 实验步骤&#xff1a; 第一步&#xff1a;地址规划拓扑设计&#xff0c;配置IP地址 R1配置&#xff1a; <Huawei>system-view [Huawei]sy R1 [R1]int g 0/0/1 [R1-GigabitEthernet0/0/1]ip address 192.168.1.1 24 [R1-GigabitEthernet0/0/1]in…