C语言socket编程开发应用示例

下面是关于C语言Socket编程开发应用示例的完整攻略:

什么是Socket编程?

Socket是计算机网络通信中的一种方式,它定义了两个网络应用程序之间的通信规则。Socket编程是指利用Socket进行网络编程,实现网络通信的一种技术。

Socket编程的基础知识

Socket编程主要有两个重要的函数:socket()和bind()。其中,socket()函数用于创建一个Socket,而bind()函数则是将一个Socket与一个本地IP地址和端口号绑定,使得其可以接受来自外部的连接请求。

下面是使用socket()和bind()函数创建和绑定Socket的示例代码:

#include <stdio.h>
#include <sys/socket.h>
#include <netinet/in.h>

int main() {
    int sockfd, newsockfd, portno;
    socklen_t clilen;
    char buffer[256];
    struct sockaddr_in serv_addr, cli_addr;   
    int n;

    // 创建Socket
    sockfd = socket(AF_INET, SOCK_STREAM, 0);   
    if (sockfd < 0) {
        perror("ERROR opening socket");
        return 1;
    }

    // 绑定Socket
    bzero((char *) &serv_addr, sizeof(serv_addr));
    portno = 8080;
    serv_addr.sin_family = AF_INET;
    serv_addr.sin_addr.s_addr = INADDR_ANY;
    serv_addr.sin_port = htons(portno);
    if (bind(sockfd, (struct sockaddr *) &serv_addr, sizeof(serv_addr)) < 0) {
        perror("ERROR on binding");
        close(sockfd);
        return 1;
    }

    // 监听Socket
    listen(sockfd, 5);
    clilen = sizeof(cli_addr);

    // 接收连接
    newsockfd = accept(sockfd, (struct sockaddr *) &cli_addr, &clilen);
    if (newsockfd < 0) {
        perror("ERROR on accept");
        close(sockfd);
        return 1;
    }

    // 读取数据
    bzero(buffer, 256);
    n = read(newsockfd, buffer, 255);
    if (n < 0) {
        perror("ERROR reading from socket");
        close(newsockfd);
        close(sockfd);
        return 1;
    }
    printf("Here is the message: %s\n", buffer);

    // 向客户端发送数据
    n = write(newsockfd, "I got your message", 18);
    if (n < 0) {
        perror("ERROR writing to socket");
        close(newsockfd);
        close(sockfd);
        return 1;
    }

    // 关闭Socket
    close(newsockfd);
    close(sockfd);

    return 0;
}

上述代码将创建一个Socket并绑定到本地的8080端口,随后进入监听状态。该程序支持一个客户端连接请求,一旦收到连接请求就会向客户端发送"I got your message"消息。

Socket编程应用实例

现在我们将使用Socket编程来创建一个简单的客户端/服务器应用程序。在这个例子中,客户端将向服务器请求当前时间,然后服务器将向客户端返回当前时间并在客户端上打印。

服务器端代码

#include <stdio.h>
#include <stdlib.h>
#include <time.h>
#include <sys/socket.h>
#include <netinet/in.h>

int main() {
    int sockfd, newsockfd, portno;
    socklen_t clilen;
    char buffer[256];
    struct sockaddr_in serv_addr, cli_addr;   
    int n;

    // 创建Socket
    sockfd = socket(AF_INET, SOCK_STREAM, 0);   
    if (sockfd < 0) {
        perror("ERROR opening socket");
        return 1;
    }

    // 绑定Socket
    bzero((char *) &serv_addr, sizeof(serv_addr));
    portno = 8080;
    serv_addr.sin_family = AF_INET;
    serv_addr.sin_addr.s_addr = INADDR_ANY;
    serv_addr.sin_port = htons(portno);
    if (bind(sockfd, (struct sockaddr *) &serv_addr, sizeof(serv_addr)) < 0) {
        perror("ERROR on binding");
        close(sockfd);
        return 1;
    }

    // 监听Socket
    listen(sockfd, 5);
    clilen = sizeof(cli_addr);

    // 接收连接请求
    newsockfd = accept(sockfd, (struct sockaddr *) &cli_addr, &clilen);
    if (newsockfd < 0) {
        perror("ERROR on accept");
        close(sockfd);
        return 1;
    }

    // 读取数据
    bzero(buffer, 256);
    n = read(newsockfd, buffer, 255);
    if (n < 0) {
        perror("ERROR reading from socket");
        close(newsockfd);
        close(sockfd);
        return 1;
    }

    // 获取当前时间
    time_t t;
    time(&t);
    struct tm *local = localtime(&t);
    char *result = asctime(local);

    // 向客户端发送数据
    n = write(newsockfd, result, strlen(result));
    if (n < 0) {
        perror("ERROR writing to socket");
        close(newsockfd);
        close(sockfd);
        return 1;
    }

    // 关闭Socket
    close(newsockfd);
    close(sockfd);

    return 0;
}

客户端代码

#include <stdio.h>
#include <stdlib.h>
#include <sys/socket.h>
#include <netinet/in.h>
#include <netdb.h>

int main() {
    int sockfd, portno, n;
    struct sockaddr_in serv_addr;
    struct hostent *server;

    char buffer[256];
    portno = 8080;

    // 创建Socket
    sockfd = socket(AF_INET, SOCK_STREAM, 0);
    if (sockfd < 0) {
        perror("ERROR opening socket");
        return 1;
    }

    // 获取指定主机的信息
    server = gethostbyname("localhost");
    if (server == NULL) {
        perror("ERROR, no such host");
        return 1;
    }

    // 初始化服务器地址
    bzero((char *) &serv_addr, sizeof(serv_addr));
    serv_addr.sin_family = AF_INET;
    bcopy((char *) server->h_addr, (char *) &serv_addr.sin_addr.s_addr, server->h_length);
    serv_addr.sin_port = htons(portno);

    // 连接服务器
    if (connect(sockfd, (struct sockaddr *) &serv_addr, sizeof(serv_addr)) < 0) {
        perror("ERROR connecting");
        return 1;
    }

    // 向服务器发送请求
    n = write(sockfd, "Please send me current time.", 29);
    if (n < 0) {
        perror("ERROR writing to socket");
        close(sockfd);
        return 1;
    }

    // 从服务器接收结果
    bzero(buffer, 256);
    n = read(sockfd, buffer, 255);
    if (n < 0) {
        perror("ERROR reading from socket");
        close(sockfd);
        return 1;
    }

    // 打印当前时间
    printf("%s", buffer);

    // 关闭Socket
    close(sockfd);

    return 0;
}

在上述客户端/服务器应用程序中,客户端向服务器发送"Please send me current time."请求,一旦接收到请求,服务器将会返回当前时间。

我希望本攻略对你有所帮助。

本站文章如无特殊说明,均为本站原创,如若转载,请注明出处:C语言socket编程开发应用示例 - Python技术站

(0)
上一篇 2023年5月22日
下一篇 2023年5月22日

相关文章

  • C语言小程序 杨辉三角示例代码

    下面我来为您详细讲解“C语言小程序 杨辉三角示例代码”的攻略。 什么是杨辉三角 杨辉三角,又称帕斯卡三角形,是二项式系数在三角形中的一种几何排列。它是中国古代数学的杰出研究成果之一,杨辉是唐朝末年、宋朝初年的一位著名数学家。 杨辉三角的规律是:每个数等于它上方两数之和。它的形状如下图所示: 1 1 1 1 2 1 1 3 3 1 1 4 6 4 1 1 5 …

    C 2023年5月23日
    00
  • 详解c++ libuv工作队列

    当我们写高并发和高性能的程序时,需要考虑为多个并发任务安排合适的执行顺序,以避免出现竞争和死锁等问题。此时,工作队列就是一个非常灵活且高效的解决方案,我们可以用工作队列管理并发状态的转移和处理。 C++ Libuv是一个跨平台异步IO库,同时提供了事件循环和工作队列的支持。下面我们将详细讲解如何使用C++ Libuv的工作队列。 创建工作队列 要想使用工作队…

    C 2023年5月22日
    00
  • 在Linux系统上进行openmp多线程编程的方法

    在Linux系统上进行OpenMP多线程编程的方法如下: 1. 安装OpenMP库和编译器 在Linux系统中使用OpenMP多线程编程需要安装OpenMP库和编译器。在大多数Linux系统上,OpenMP库和编译器可以通过包管理工具安装。例如,在Ubuntu系统中,可以通过以下命令安装: sudo apt-get install libomp-dev g+…

    C 2023年5月22日
    00
  • js数组与字符串常用方法总结

    JS数组与字符串常用方法总结 本篇攻略主要介绍 JavaScript 中数组和字符串的常用方法。 数组 1. 创建数组 数组可以通过以下方式进行创建: var arr1 = []; // 空数组 var arr2 = new Array(); // 空数组 var arr3 = [1, 2, 3]; // 带有元素的数组 2. 数组的常用方法 2.1 pus…

    C 2023年5月22日
    00
  • 从创建数据库到存储过程与用户自定义函数的小感

    创建数据库到存储过程与用户自定义函数 一、创建数据库 创建数据库需要执行以下操作: CREATE DATABASE database_name; 其中,database_name为你要创建的数据库名称。 二、创建表 创建表需要执行以下操作: CREATE TABLE table_name( column1 datatype constraints, colu…

    C 2023年5月23日
    00
  • C++11 shared_ptr 与 make_shared源码剖析详解

    C++11中的shared_ptr和make_shared是两个非常实用的特性,能够帮助我们更好地管理内存。本文将深入介绍shared_ptr和make_shared的实现原理,帮助读者更好地掌握这两个特性。 1. shared_ptr简介 shared_ptr是C++11提供的一种智能指针,用于管理动态内存。它可以自动对内存进行引用计数,并在引用计数为0时…

    C 2023年5月23日
    00
  • 比特币原理是什么?比特币原理详解

    比特币原理是什么? 比特币(Bitcoin)是一种去中心化的数字货币,是基于点对点网络技术和密码学算法实现的。它的核心原领是区块链技术,是一种分布式账本技术,使得比特币能够实现去中心化、防篡改。 比特币采用共识机制来保证交易的安全和可靠性。它没有中心化的发行机构,每一笔交易都被记录到区块链上。同时,比特币的发行数量是有限的,最大发行量不超过2100万枚。 比…

    C 2023年5月22日
    00
  • 深入解析C++编程中线程池的使用

    深入解析C++编程中线程池的使用 什么是线程池? 线程池是一种用来集中处理线程的机制。线程池内包含多个线程,它们可以处理分配给线程池的任务。线程池在系统启动时就被初始化,一直运行到系统关闭。 为什么需要使用线程池? 线程池的好处是可以优化系统性能,通过重复利用已存在的线程,避免了频繁创建和销毁线程的开销。并且线程池可以缓解程序因为大量线程占用系统资源,导致系…

    C 2023年5月22日
    00
合作推广
合作推广
分享本页
返回顶部