首页 > 编程语言 >socket网络编程

socket网络编程

时间:2023-04-18 10:44:29浏览次数:32  
标签:addr ip 编程 网络 len fd sizeof buff socket

下面分别以TCP、UDP为例介绍两者的流程图和代码实现:

  • TCP
1.流程图:   和网上大部分的版本不同,我将TCP三次握手的过程画在了accpet之前,这也是在查阅一些资料发现三次握手会由内核自动完成,aceept只是从队列中取出已经建好的tcp连接,这一点可以在代码中不加入accpet以及后续步骤验证。

2.代码实现:   server端:
#include <stdio.h>
#include <stdlib.h>
#include <unistd.h>
#include <string.h>
#include <arpa/inet.h>

#define SERVER_PORT 8888
#define SERVER_IP "192.168.1.100"

int main()
{
    // 1. 创建监听套接字
    int fd = socket(AF_INET, SOCK_STREAM, 0);
    if (fd == -1)
    {
        perror("fail fo socket!");
        return -1;
    }
    printf("create socket fd[%d] success!\n");

    // 2. 绑定监听套接字到本地IP和port
    struct sockaddr_in addr;
    addr.sin_family = AF_INET;
    addr.sin_port = htons(SERVER_PORT);
    inet_pton(AF_INET, SERVER_IP, &addr.sin_addr);
    int ret = bind(fd, (struct sockaddr*)&addr, sizeof(addr));
    if (ret == -1)
    {
        perror("fail to bind!");
        return -2;
    }
    printf("bind success!\n");

    // 3. 设置监听
    ret = listen(fd, 128);
    if (ret == -1)
    {
        perror("fail to listen!");
        return -3;
    }
    printf("listen success!\n");

    // 4. 阻塞等待,等待连接到达,连接成功后返回通信用的套接字
    struct sockaddr_in c_addr;
    int c_addr_len = sizeof(c_addr);
    int c_fd = accept(fd, (struct sockaddr*)&c_addr, &c_addr_len);
    if (c_fd == -1)
    {
        perror("fail to accept!");
        return -4;
    }
    printf("accept success!\n");

    // 5. 开始通信
    char buff[1024];
    char ip[32];
    memset(buff, 0, sizeof(buff));
    memset(ip, 0, sizeof(ip));
    int len = read(c_fd, buff, sizeof(buff));
    if (len > 0)
    {
        printf("client %s:%d >> %s\n", inet_ntop(AF_INET, &c_addr.sin_addr, ip , sizeof(ip)), ntohs(c_addr.sin_port), buff);
        write(c_fd, buff, len);
    }
    else if (len == 0)
    {
        printf("connect close!");
    }
    else
    {
        printf("connect fail!");
    }

    // 6. 关闭套接字
    close(fd);
    close(c_fd);
    return 0;
}
client端:
#include <stdio.h>
#include <stdlib.h>
#include <unistd.h>
#include <string.h>
#include <arpa/inet.h>

#define SERVER_PORT 8888
#define SERVER_IP "192.168.1.100"

int main()
{
    // 1. 创建通信套接字
    int fd = socket(AF_INET, SOCK_STREAM, 0);
    if (fd == -1)
    {
        perror("fail fo socket!");
        return -1;
    }
    printf("create socket success!\n");

    // 2. 连接服务器
    struct sockaddr_in addr;
    addr.sin_family = AF_INET;
    addr.sin_port = htons(SERVER_PORT);
    inet_pton(AF_INET, SERVER_IP, &addr.sin_addr);
    int ret = connect(fd, (struct sockaddr*)&addr, sizeof(addr));
    if (ret == -1)
    {
        perror("fail to connect!");
        return -2;
    }
    printf("connect success!\n");

    // 3. 通信
    char buff[1024];
    char ip[32];
    sprintf(buff, "Hello, this is a test connection with the server!");
    int len = send(fd, buff, strlen(buff) + 1, 0);
    memset(buff, 0, sizeof(buff));
    memset(ip, 0, sizeof(ip));
    len = recv(fd, buff, sizeof(buff), 0);
    if (len > 0)
    {
        printf("server %s:%d >> %s\n", inet_ntop(AF_INET, &addr.sin_addr, ip , sizeof(ip)), ntohs(addr.sin_port), buff);
    }
    else if (len == 0)
    {
        printf("connect close!\n");
    }
    else
    {
        perror("recv fail!\n");
    }

    // 4. 关闭套接字
    close(fd);
    return 0;
}
上述代码就是实现一个简单的socket通信过程,服务器和客户端收发一次消息后便关闭通信。 就是上面一个简单的通信过程,发现实现起来也并非一帆风顺,途中数次碰到问题,下面记录下踩到的一些坑: 1.fail to connect!: No route to host server端代码和client端代码分别在两台虚拟机上运行时,client端一运行就报fail to connect!: No route to host错误,检查发现双发是能否ping通,搜索发现可能是防火墙打开导致这个问题,使用以下命令查看防火墙是开着的:
[root@localhost socket]# systemctl status firewalld.service
● firewalld.service - firewalld - dynamic firewall daemon
   Loaded: loaded (/usr/lib/systemd/system/firewalld.service; enabled; vendor preset: enabled)
   Active: active (running) since Fri 2022-12-30 21:44:51 EST; 42min ago
     Docs: man:firewalld(1)
 Main PID: 693 (firewalld)
   CGroup: /system.slice/firewalld.service
           └─693 /usr/bin/python2 -Es /usr/sbin/firewalld --nofork --nopid

Dec 30 21:44:50 localhost.localdomain systemd[1]: Starting firewalld - dynamic firewall daemon...
Dec 30 21:44:51 localhost.localdomain systemd[1]: Started firewalld - dynamic firewall daemon.
Dec 30 21:44:51 localhost.localdomain firewalld[693]: WARNING: AllowZoneDrifting is enabled. This is considered an insecure configur...t now.
Hint: Some lines were ellipsized, use -l to show in full.
试着关闭防火墙后运行了下程序,发现能成功通信,果然是防火墙的原因。 2.server端显示client的ip和port错误 在运行上述代码时,发现在server端打印连接的client的ip和port一直都有问题并非实际的ip和port。排查了半天才发现传给accpet的第三个参数是表示sockaddr结构体的大小,并非随便传一个值都行。
struct sockaddr_in c_addr;
int c_addr_len = sizeof(c_addr);
int c_fd = accept(fd, (struct sockaddr*)&c_addr, &c_addr_len);

 

标签:addr,ip,编程,网络,len,fd,sizeof,buff,socket
From: https://www.cnblogs.com/chien/p/17328746.html

相关文章

  • UNIX环境高级编程 第三版 源代码编译及使用
    UNIX环境高级编程(第3版)中的代码示例多次包含了一下头文件:#include"apue.h"搜索发现原来这个头文件是作者自定义的一个文件,并在官网提供了源代码供下载。下载之后解压该文件:tar-zxfsrc.3e.tar.gz进入文件夹并编译:cdapue.3emake等待结束,如果没有报错就成功了。(如......
  • Socket学习网络基础
    1.OSI七层网络模型浅析当然,我们不是专业搞网络工程的,只要知道有哪些层,大概是拿来干嘛的就可以了!OSI七层网络模型(从下往上):物理层(Physical):设备之间的数据通信提供传输媒体及互连设备,为数据传输提供可靠的环境。可以理解为网络传输的物理媒体部分,比如网卡,网线,集线器,中继器,调制解调......
  • 网络编程
    网络编程概述网络编程就是在网络通信协议下,不同计算机上运行的程序,进行的数据传送。本质就是不同计算机之间通过网络进行数据传送。java中可用java.net包下的技术,开发出常见的网络应用程序。常见的软件架构:B/S架构:Browser/Server,即浏览器/服务器的架构只需要一个浏览器,用......
  • 业余爱好者想入门编程,一定远离那些只会说No的家伙,尤其程序员
    视频:https://haokan.baidu.com/v?pd=wisenatural&vid=3050207991292418741自媒体上的程序员群体有一个非常有意思的特点,就是特别愿意否定别人,特别喜欢说no,还有一个特点,特别不爱分享一些有用的技术和知识,你就看吧,就是在B站也好,在西瓜也好,很多很多露脸的程序员。几乎不跟你讲那......
  • 2023.4.17编程一小时打卡
    一、问题描述:设计一款电子钟类,用于显示时、分、秒。实验要求:含有形参有默认值的默认构造函数;重载前缀++和后缀—用于调整时间,每次调整均对秒进行调整,若秒满60,则分加1,若分满60则时加1,时满24,则清零重新开始;重载插入运算符>>用于输入(设定)时间;重载插入运算符<<用于输出......
  • 每日编程一小时(第八天)
    一.问题描述专家通过多组情侣研究数据发现,最佳的情侣身高差遵循着一个公式:(女方的身高)×1.09=(男方的身高)。如果符合,你俩的身高差不管是牵手、拥抱、接吻,都是最和谐的差度。下面就请你写个程序,为任意一位用户计算他/她的情侣的最佳身高。二.设计思路1.创建一个结构体类型包含性......
  • 结对编程——300道小学四则运算
    本次结对编程作业由我和2152620同学使用c++语言共同完成。代码如下:#include<iomanip>#include<iostream>#include<ctime>#include<cstdlib>usingnamespacestd;intnum1[300];intnum2[300];intop[300];intanswer[300];intreal[300];voidsrand(unsigne......
  • 华为云等保合规方案,守护企业网络安全线
    要想了解华为云等保合规,先要了解华为云安全。现今数字化智能时代已成为趋势,而安全则是一个企业的生命线,在网络上需要构建一个安全可靠的防御系统,而这并非一件简单的事情。绝大部分的企业考虑网站内的安全合规性,会选择一款适应的产品保护网站的基本安全,华为云在这方面“更可靠,技术强......
  • IDL编程读取影像处理影像
    IDL(InteractiveDataLanguage)是一种用于科学数据处理和可视化的编程语言,可以用来读取和处理影像数据。以下是一个简单的IDL代码片段,用于读取一幅影像并进行一些基本的处理:;打开一幅影像file='myimage.tif'raster=raster_open(file);读取影像的大小size=raster->get_siz......
  • 基于FNN模糊神经网络的控制器解耦控制matlab仿真
    1.算法仿真效果matlab2022a仿真结果如下:2.算法涉及理论知识概要系统的复杂性与所要求的精确性之间存在尖锐矛盾,为此,通过模拟人类学习和自适应能力,人们提出了智能控制的思想。控制理论专家Austrom(1991)在IFAC大会上指出:模糊逻辑控制、神经网络与专家控制是三种典型的智能控制......