Linux下网络编程(3)——socket编程实战,如何构建一个服务器和客户端连接

这篇具有很好参考价值的文章主要介绍了Linux下网络编程(3)——socket编程实战,如何构建一个服务器和客户端连接。希望对大家有所帮助。如果存在错误或未考虑完全的地方,请大家不吝赐教,您也可以点击"举报违法"按钮提交疑问。

        经过前几篇的介绍,本文我们将进行编程实战,实现一个简单地服务器和客户端应用程序。

编写服务器程序

        编写服务器应用程序的流程如下:

        ①、调用 socket()函数打开套接字,得到套接字描述符;

        ②、调用 bind()函数将套接字与 IP 地址、端口号进行绑定;

        ③、调用 listen()函数让服务器进程进入监听状态;

        ④、调用 accept()函数获取客户端的连接请求并建立连接;

        ⑤、调用 read()/recv()、write()/send() 与客户端进行通信;

        ⑥、调用 close()关闭套接字。

        下面,我们就根据上面列举的步骤来编写一个简单的服务器应用程序,代码如下所示:

#include <stdio.h>
#include <stdlib.h>
#include <unistd.h>
#include <string.h>
#include <sys/types.h>
#include <sys/socket.h>
#include <arpa/inet.h>
#include <netinet/in.h>

#define SERVER_PORT     8888    //端口号不能发生冲突,不常用的端口号通常大于5000

int main(void){
    struct sockaddr_in server_addr = {0};
    struct sockaddr_in client_addr = {0};
    char ip_str[20] = {0};
    int sockfd, connfd;
    int addrlen = sizeof(client_addr);
    char recvbuf[512];
    int ret;

    /* 打开套接字,得到套接字描述符 */
    sockfd = socket(AF_INET, SOCK_STREAM, 0);
    if (0 > sockfd) {
        perror("socket error");
        exit(EXIT_FAILURE);
    }

    /* 将套接字与指定端口号进行绑定 */
    server_addr.sin_family = AF_INET;
    server_addr.sin_addr.s_addr = htonl(INADDR_ANY);
    server_addr.sin_port = htons(SERVER_PORT);

    ret = bind(sockfd, (struct sockaddr *)&server_addr, sizeof(server_addr));
    if (0 > ret) {
        perror("bind error");
        close(sockfd);
        exit(EXIT_FAILURE);
    }

    /* 使服务器进入监听状态 */
    ret = listen(sockfd, 50);
    if (0 > ret) {
        perror("listen error");
        close(sockfd);
        exit(EXIT_FAILURE);
    }

    /* 阻塞等待客户端连接 */
    connfd = accept(sockfd, (struct sockaddr *)&client_addr, &addrlen);
    if (0 > connfd) {
        perror("accept error");
        close(sockfd);
        exit(EXIT_FAILURE);
    }
    printf("有客户端接入...\n");
    inet_ntop(AF_INET, &client_addr.sin_addr.s_addr, ip_str, sizeof(ip_str));
    printf("客户端主机的IP地址: %s\n", ip_str);
    printf("客户端进程的端口号: %d\n", client_addr.sin_port);

    /* 接收客户端发送过来的数据 */
    for ( ; ; ) {
        // 接收缓冲区清零
        memset(recvbuf, 0x0, sizeof(recvbuf));

        // 读数据
        ret = recv(connfd, recvbuf, sizeof(recvbuf), 0);
        if(0 >= ret) {
            perror("recv error");
            close(connfd);
            break;
        }
        // 将读取到的数据以字符串形式打印出来
        printf("from client: %s\n", recvbuf);

        // 如果读取到"exit"则关闭套接字退出程序
        if (0 == strncmp("exit", recvbuf, 4)) {
            printf("server exit...\n");
            close(connfd);
            break;
        }
    }
    /* 关闭套接字 */
    close(sockfd);
    exit(EXIT_SUCCESS);
}

        以上我们实现了一个非常简单地服务器应用程序,根据上面列举的步骤完成了这个示例代码,最终的功能是,当客户端连接到服务器之后,客户端会向服务器(也就是本程序)发送数据,在我们服务器应用程序中会读取客户端发送的数据并将其打印出来,就是这么简单的一个功能。

        SERVER_PORT 宏指定了本服务器绑定的端口号,这里我们将端口号设置为 8888,端口不能与其它服务器的端口号发生冲突,不常用的端口号通常大于 5000。

        另外,bind绑定的IP地址是 INADDR_ANY,即表示所有发送到服务器的这个端口,不管是哪个网卡/哪个IP地址接收到的数据,都由这个服务端进程进行处理。

编写客户端程序

        接下来我们再编写一个简单地客户端应用程序,客户端的功能是连接上小节所实现的服务器,连接成功之后向服务器发送数据,发送的数据由用户输入。示例代码如下所示:

#include <stdio.h>
#include <stdlib.h>
#include <unistd.h>
#include <string.h>
#include <sys/types.h>
#include <sys/socket.h>
#include <arpa/inet.h>
#include <netinet/in.h>

#define SERVER_PORT		8888          	//服务器的端口号
#define SERVER_IP   	"192.168.1.150"	//服务器的IP地址

int main(void){
    struct sockaddr_in server_addr = {0};
    char buf[512];
    int sockfd;
    int ret;

    /* 打开套接字,得到套接字描述符 */
    sockfd = socket(AF_INET, SOCK_STREAM, 0);
    if (0 > sockfd) {
        perror("socket error");
        exit(EXIT_FAILURE);
    }

    /* 调用connect连接远端服务器 */
    server_addr.sin_family = AF_INET;
    server_addr.sin_port = htons(SERVER_PORT);  //端口号
    inet_pton(AF_INET, SERVER_IP, &server_addr.sin_addr);//IP地址
    ret = connect(sockfd, (struct sockaddr *)&server_addr, sizeof(server_addr));
    if (0 > ret) {
        perror("connect error");
        close(sockfd);
        exit(EXIT_FAILURE);
    }
    printf("服务器连接成功...\n\n");

    /* 向服务器发送数据 */
    for ( ; ; ) {
        // 清理缓冲区
        memset(buf, 0x0, sizeof(buf));

        // 接收用户输入的字符串数据
        printf("Please enter a string: ");
        fgets(buf, sizeof(buf), stdin);

        // 将用户输入的数据发送给服务器
        ret = send(sockfd, buf, strlen(buf), 0);
        if(0 > ret){
            perror("send error");
            break;
        }

        //输入了"exit",退出循环
        if(0 == strncmp(buf, "exit", 4))
            break;
    }
    close(sockfd);
    exit(EXIT_SUCCESS);
}

        代码不再说明!需要注意的是 SERVER_IP 和 SERVER_PORT 指的是服务器的 IP 地址和端口号,服务器的 IP 地址根据实际情况进行设置,服务器应用程序服务器端代码中我们绑定的端口号为 8888,所以在客户端应用程序中我们也需要指定 SERVER_PORT 为 8888。

编译测试

        这里笔者将服务器程序运行在开发板上,而将客户端应用程序运行在 Ubuntu 系统,当然你也可以将客户端和服务器程序都运行在开发板或 Ubuntu 系统,这都是没问题的。

        首先编译服务器应用程序和客户端应用程序:

写出实验中linux socket通信实验的代码所在目录。 在虚拟机linux中编译并执行此代,Linux,网络,linux,网络,服务器

         编译得到 client 和 server 可执行文件,server 可执行文件在开发板上运行,client 可执行文件在 PC 端 Ubuntu 系统下运行。将 server 可执行文件拷贝到开发板目录下,如下所示:

写出实验中linux socket通信实验的代码所在目录。 在虚拟机linux中编译并执行此代,Linux,网络,linux,网络,服务器

         在开发板执行 server:

写出实验中linux socket通信实验的代码所在目录。 在虚拟机linux中编译并执行此代,Linux,网络,linux,网络,服务器

        接着在 Ubuntu 系统执行客户端程序:

写出实验中linux socket通信实验的代码所在目录。 在虚拟机linux中编译并执行此代,Linux,网络,linux,网络,服务器

         客户端运行之后将会去连接远端服务器,连接成功便会打印出信息“服务器连接成功...”,此时服务器也会监测到客户端连接,会打印相应的信息,如下所示:

写出实验中linux socket通信实验的代码所在目录。 在虚拟机linux中编译并执行此代,Linux,网络,linux,网络,服务器

        接下来我们便可以在客户端处输入字符串,客户端程序会将我们输入的字符串信息发送给服务器,服务器接收到之后将其打印出来,如下所示:

写出实验中linux socket通信实验的代码所在目录。 在虚拟机linux中编译并执行此代,Linux,网络,linux,网络,服务器

Tips : 如果连接出现问题如“connect error: No route to host”,可以参考这篇问题记录开发板和虚拟机socket报错“connect error: No route to host”。

写出实验中linux socket通信实验的代码所在目录。 在虚拟机linux中编译并执行此代,Linux,网络,linux,网络,服务器

 总结

        到此,socket编程的内容就告一段落,内容讲得非常浅,目的其实并不是让大家学会网络编程,旨在以引导大家入门为主,让大家对 socket 网络编程有一个基本的了解和认识。望诸君常学常新、学思践悟。 文章来源地址https://www.toymoban.com/news/detail-772169.html

到了这里,关于Linux下网络编程(3)——socket编程实战,如何构建一个服务器和客户端连接的文章就介绍完了。如果您还想了解更多内容,请在右上角搜索TOY模板网以前的文章或继续浏览下面的相关文章,希望大家以后多多支持TOY模板网!

本文来自互联网用户投稿,该文观点仅代表作者本人,不代表本站立场。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如若转载,请注明出处: 如若内容造成侵权/违法违规/事实不符,请点击违法举报进行投诉反馈,一经查实,立即删除!

领支付宝红包 赞助服务器费用

相关文章

  • Linux网络编程:socket实现client/server通信

    阅读 UNIX网络编程 卷1:套接字联网API 第3版 的前4个章节,觉得有必要对书籍上的源码案例进行复现,并推敲TCP的C/S通信过程。 📌 测试环境:CentOS7.6 x64 编译server.c 和 client.c gcc server.c -g -std=gnu99 -o server 和 gcc client.c -g -std=gnu99 -o client 运行测试: 📌 server.c仅仅实现对单个客户

    2024年02月03日
    浏览(29)
  • Linux网络编程- 原始套接字(Raw Socket)

    原始套接字(Raw Socket)提供了一种机制,允许应用程序直接访问底层传输协议,绕过操作系统提供的传输层接口。这种套接字通常用于实现新的协议或对现有协议进行低级别的操作。 以下是对原始套接字的详细介绍: 定义与用途 : 原始套接字是直接基于网络层(如IP)的。

    2024年02月07日
    浏览(33)
  • 【Linux网络】网络编程套接字 -- 基于socket实现一个简单UDP网络程序

    我们把数据从A主机发送到B主机,是目的吗?不是,真正通信的不是这两个机器!其实是这两台机器上面的软件(人) 数据有 IP(公网) 标识一台唯一的主机 ,用谁来标识各自主机上客户或者服务进程的唯一性呢? 为了更好的表示一台主机上服务进程的唯一性,我们采用 端口号

    2024年02月12日
    浏览(39)
  • Linux网络编程:socket、客户端服务器端使用socket通信(TCP)

    socket(套接字),用于网络中不同主机间进程的通信。 socket是一个伪文件,包含读缓冲区、写缓冲区。 socket必须成对出现。 socket可以建立主机进程间的通信,但需要协议(IPV4、IPV6等)、port端口、IP地址。          (1)创建流式socket套接字。                 a)此s

    2024年02月11日
    浏览(45)
  • 【探索Linux】—— 强大的命令行工具 P.26(网络编程套接字基本概念—— socket编程接口 | socket编程接口相关函数详细介绍 )

    本文将深入探讨使用套接字进行网络通信的基本步骤,包括创建套接字、绑定地址、监听连接(对于服务器端)、连接远程主机(对于客户端)、以及发送和接收数据等操作。套接字编程涉及一系列系统调用和函数,如 socket() 、 bind() 、 listen() 、 connect() 、 send() 、 recv() 等。

    2024年03月10日
    浏览(63)
  • Linux网络编程:socket & fork实现clients/server通信

    UNIX网络编程:socket实现client/server通信 随笔简单介绍了TCP Server服务单客户端的socket通信,但是并未涉及多客户端通信。 对于网络编程肯定涉及到多客户端通信和并发编程 (指在同时有大量的客户链接到同一服务器),故本随笔补充这部分知识。 而且并发并发编程涉及到多进程

    2024年02月05日
    浏览(37)
  • Linux网络编程:Socket套接字编程(Server服务器 Client客户端)

    文章目录: 一:定义和流程分析 1.定义 2.流程分析  3.网络字节序 二:相关函数  IP地址转换函数inet_pton inet_ntop(本地字节序 网络字节序) socket函数(创建一个套接字) bind函数(给socket绑定一个服务器地址结构(IP+port)) listen函数(设置最大连接数或者说能同时进行三次握手的最

    2024年02月12日
    浏览(67)
  • C/C++ Linux Socket网络编程 TCP 与 UDP

    之前已经学习了QT的socket编程 和 C/C++在window环境的socket编程,现在再来学习一波C/C++在Linux环境下的socket编程,为以后学习C++ Linux 服务器开发做准备。 目录 一、Socket简介 二、Socket编程基础 1. 网络字节序 2. sockaddr数据结构 3. IP地址转换函数 三、TCP编程函数 1. socket函数 2. bi

    2024年02月02日
    浏览(45)
  • Linux学习之网络编程2(socket,简单C/S模型)

    Linux网络编程我是看视频学的,Linux网络编程,看完这个视频大概网络编程的基础差不多就掌握了。这个系列是我看这个Linux网络编程视频写的笔记总结。 小端法:pc本地存储,高位存高地址,低位存低地址。 大端法:网络存储,高位存低地址,低位存高地址。 由此我们看到

    2024年02月01日
    浏览(39)
  • Linux网络编程:socket & fork()多进程 实现clients/server通信

    UNIX网络编程:socket实现client/server通信 随笔简单介绍了TCP Server服务单客户端的socket通信,但是并未涉及多客户端通信。 对于网络编程肯定涉及到多客户端通信和并发编程 (指在同时有大量的客户链接到同一服务器),故本随笔补充这部分知识。 而且并发并发编程涉及到多进程

    2024年02月05日
    浏览(34)

觉得文章有用就打赏一下文章作者

支付宝扫一扫打赏

博客赞助

微信扫一扫打赏

请作者喝杯咖啡吧~博客赞助

支付宝扫一扫领取红包,优惠每天领

二维码1

领取红包

二维码2

领红包