Socket编程详解:从基本概念到实例应用(TCP|UDP C语言实例详解)

这篇具有很好参考价值的文章主要介绍了Socket编程详解:从基本概念到实例应用(TCP|UDP C语言实例详解)。希望对大家有所帮助。如果存在错误或未考虑完全的地方,请大家不吝赐教,您也可以点击"举报违法"按钮提交疑问。

简介:
Socket编程是网络编程中至关重要的一部分,它提供了一种在不同主机之间进行数据通信的方式。本篇博客将详细介绍Socket编程的基本概念、原理和实例应用,帮助读者深入理解和掌握这一重要技术。

正文:
一、Socket编程概述
Socket是一种通信机制,通过它可以在不同主机之间进行数据交换。在Socket编程中,有两种常见的通信模式:客户端-服务器模式和点对点模式。它基于TCP/IP协议栈,并使用IP地址和端口号来标识通信的目标。

二、Socket编程基本步骤
Socket编程是一种用于实现网络通信的编程接口,可以通过TCP(传输控制协议)和UDP(用户数据报协议)实现不同类型的连接。下面将详细介绍TCP和UDP的开发流程,并详细介绍常用的Socket编程函数的原型和参数用法。

TCP开发流程:

  1. 服务器端:

    • 创建套接字:int serverSocket = socket(AF_INET, SOCK_STREAM, 0);
    • 绑定地址:struct sockaddr_in serverAddress; serverAddress.sin_family = AF_INET; serverAddress.sin_port = htons(port); serverAddress.sin_addr.s_addr = INADDR_ANY; bind(serverSocket, (struct sockaddr*)&serverAddress, sizeof(serverAddress));
    • 监听连接:listen(serverSocket, backlog);
    • 接受连接:struct sockaddr_in clientAddress; int clientSocket = accept(serverSocket, (struct sockaddr*)&clientAddress, sizeof(clientAddress));
    • 发送和接收数据:send(clientSocket, buffer, size, 0); recv(clientSocket, buffer, size, 0);
    • 关闭连接:close(clientSocket); close(serverSocket);
  2. 客户端:

    • 创建套接字:int clientSocket = socket(AF_INET, SOCK_STREAM, 0);
    • 连接服务器:struct sockaddr_in serverAddress; serverAddress.sin_family = AF_INET; serverAddress.sin_port = htons(port); serverAddress.sin_addr.s_addr = inet_addr(serverIP); connect(clientSocket, (struct sockaddr*)&serverAddress, sizeof(serverAddress));
    • 发送和接收数据:send(clientSocket, buffer, size, 0); recv(clientSocket, buffer, size, 0);
    • 关闭连接:close(clientSocket);

UDP开发流程:

  1. 服务器端:

    • 创建套接字:int serverSocket = socket(AF_INET, SOCK_DGRAM, 0);
    • 绑定地址:struct sockaddr_in serverAddress; serverAddress.sin_family = AF_INET; serverAddress.sin_port = htons(port); serverAddress.sin_addr.s_addr = INADDR_ANY; bind(serverSocket, (struct sockaddr*)&serverAddress, sizeof(serverAddress));
    • 接收和发送数据:recvfrom(serverSocket, buffer, size, 0, (struct sockaddr*)&clientAddress, sizeof(clientAddress)); sendto(serverSocket, buffer, size, 0, (struct sockaddr*)&clientAddress, sizeof(clientAddress));
    • 关闭套接字:close(serverSocket);
  2. 客户端:

    • 创建套接字:int clientSocket = socket(AF_INET, SOCK_DGRAM, 0);
    • 发送和接收数据:sendto(clientSocket, buffer, size, 0, (struct sockaddr*)&serverAddress, sizeof(serverAddress)); recvfrom(clientSocket, buffer, size, 0, (struct sockaddr*)&serverAddress, sizeof(serverAddress));
    • 关闭套接字:close(clientSocket);

常用函数的原型和参数用法详解:

  1. socket()函数:
    • 原型:int socket(int domain, int type, int protocol);
    • 参数:
      • domain:地址族,通常为AF_INET(IPv4)或AF_INET6(IPv6)。
      • type:套接字类型,可以是SOCK_STREAM(TCP)或SOCK_DGRAM(UDP)。
      • protocol:协议,通常为0,表示自动选择合适的协议。

2

. bind()函数:

  • 原型:int bind(int sockfd, const struct sockaddr *addr, socklen_t addrlen);
  • 参数:
    • sockfd:套接字描述符。
    • addr:指向本地地址结构体的指针。
    • addrlen:地址结构体的长度。
  1. listen()函数:

    • 原型:int listen(int sockfd, int backlog);
    • 参数:
      • sockfd:套接字描述符。
      • backlog:待连接队列的最大长度。
  2. accept()函数:

    • 原型:int accept(int sockfd, struct sockaddr *addr, socklen_t *addrlen);
    • 参数:
      • sockfd:套接字描述符。
      • addr:指向客户端地址结构体的指针,用于存储客户端的地址信息。
      • addrlen:指向地址结构体长度的指针。
  3. connect()函数:

    • 原型:int connect(int sockfd, const struct sockaddr *addr, socklen_t addrlen);
    • 参数:
      • sockfd:套接字描述符。
      • addr:指向目标地址结构体的指针。
      • addrlen:地址结构体的长度。
  4. send()函数:

    • 原型:ssize_t send(int sockfd, const void *buf, size_t len, int flags);
    • 参数:
      • sockfd:套接字描述符。
      • buf:指向要发送数据的缓冲区的指针。
      • len:要发送的数据的长度。
      • flags:发送标志,通常为0。
  5. recv()函数:

    • 原型:ssize_t recv(int sockfd, void *buf, size_t len, int flags);
    • 参数:
      • sockfd:套接字描述符。
      • buf:指向接收数据的缓冲区的指针。
      • len:要接收的数据的最大长度。
      • flags:接收标志,通常为0。
  6. sendto()函数:

    • 原型:ssize_t sendto(int sockfd, const void *buf, size_t len, int flags, const struct sockaddr *dest_addr, socklen_t addrlen);
    • 参数:
      • sockfd:套接字描述符。
      • buf:指向要发送数据的缓冲区的指针。
      • len:要发送的数据的长度。
      • flags:发送标志,通常为0。
      • dest_addr:指向目标地址结构体的指针。
      • addrlen:目标地址结构体的长度。
  7. recvfrom()函数:

    • 原型:ssize_t recvfrom(int sockfd, void *buf, size_t len, int flags, struct sockaddr *src_addr, socklen_t *addrlen);
    • 参数:
      • sockfd:套接字描述符。
      • buf:指向接收数据的缓冲区的指针。
      • len:要接收的数据的最大长度。
      • flags:接收标志,通常为0。
      • src_addr:指向源地址结构体的指针,用于存储源地址信息。
      • addrlen:指向地址结构体长度的指针。
  8. close()函数:

原型:int close(int sockfd);
- 参数:套接字描述符。

通过使用这些函数,可以实现TCP和UDP通信的服务器端和客户端程序。TCP提供可靠的、面向连接的通信,适用于需要确保数据可靠性和顺序性的场景,而UDP提供无连接的通信,适用于实时性要求较高但可靠性要求较低的场景。

三、Socket编程实例

以下是使用C语言通过Socket实现TCP和UDP通信的服务端和客户端通信程序的示例:

TCP通信示例:

服务端(server.c):

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

#define SERVER_IP "127.0.0.1"
#define SERVER_PORT 8080
#define BUFFER_SIZE 1024

int main() {
    int serverSocket, clientSocket;
    struct sockaddr_in serverAddr, clientAddr;
    socklen_t clientAddrLen;
    char buffer[BUFFER_SIZE];

    // 创建服务端套接字
    serverSocket = socket(AF_INET, SOCK_STREAM, 0);
    if (serverSocket == -1) {
        perror("Failed to create socket");
        exit(EXIT_FAILURE);
    }

    // 设置服务器地址信息
    memset(&serverAddr, 0, sizeof(serverAddr));
    serverAddr.sin_family = AF_INET;
    serverAddr.sin_port = htons(SERVER_PORT);
    serverAddr.sin_addr.s_addr = htonl(INADDR_ANY);

    // 绑定套接字到指定地址和端口
    if (bind(serverSocket, (struct sockaddr *)&serverAddr, sizeof(serverAddr)) == -1) {
        perror("Failed to bind socket");
        exit(EXIT_FAILURE);
    }

    // 监听连接请求
    if (listen(serverSocket, 5) == -1) {
        perror("Failed to listen");
        exit(EXIT_FAILURE);
    }

    printf("Server listening on port %d...\n", SERVER_PORT);

    // 接受客户端连接
    clientAddrLen = sizeof(clientAddr);
    clientSocket = accept(serverSocket, (struct sockaddr *)&clientAddr, &clientAddrLen);
    if (clientSocket == -1) {
        perror("Failed to accept client connection");
        exit(EXIT_FAILURE);
    }

    printf("Client connected: %s\n", inet_ntoa(clientAddr.sin_addr));

    // 接收数据
    memset(buffer, 0, sizeof(buffer));
    if (recv(clientSocket, buffer, BUFFER_SIZE, 0) == -1) {
        perror("Failed to receive data");
        exit(EXIT_FAILURE);
    }

    printf("Client message: %s\n", buffer);

    // 发送响应
    strcpy(buffer, "Hello, Client!");
    if (send(clientSocket, buffer, strlen(buffer), 0) == -1) {
        perror("Failed to send data");
        exit(EXIT_FAILURE);
    }

    // 关闭套接字
    close(clientSocket);
    close(serverSocket);

    return 0;
}

客户端(client.c):

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

#define SERVER_IP "127.0.0.1"
#define SERVER_PORT 8080
#define BUFFER_SIZE 1024

int main() {
    int clientSocket;
    struct sockaddr_in serverAddr;
    char buffer[BUFFER_SIZE];

    // 创建客户端套接字
    clientSocket = socket(AF_INET, SOCK_STREAM, 0);
    if (clientSocket == -1) {
        perror("Failed to create socket");
        exit(EXIT_FAILURE);
    }

    // 设置服务器地址信息
    memset(&serverAddr, 0, sizeof(serverAddr));
    serverAddr.sin_family = AF_INET;
    serverAddr.sin_port = htons(SERVER_PORT);
    if (inet_pton(AF_INET, SERVER_IP, &(serverAddr.sin_addr)) <=

 0) {
        perror("Failed to set server IP");
        exit(EXIT_FAILURE);
    }

    // 连接到服务器
    if (connect(clientSocket, (struct sockaddr *)&serverAddr, sizeof(serverAddr)) == -1) {
        perror("Failed to connect to server");
        exit(EXIT_FAILURE);
    }

    printf("Connected to server %s:%d\n", SERVER_IP, SERVER_PORT);

    // 发送数据
    strcpy(buffer, "Hello, Server!");
    if (send(clientSocket, buffer, strlen(buffer), 0) == -1) {
        perror("Failed to send data");
        exit(EXIT_FAILURE);
    }

    // 接收响应
    memset(buffer, 0, sizeof(buffer));
    if (recv(clientSocket, buffer, BUFFER_SIZE, 0) == -1) {
        perror("Failed to receive data");
        exit(EXIT_FAILURE);
    }

    printf("Server response: %s\n", buffer);

    // 关闭套接字
    close(clientSocket);

    return 0;
}

UDP通信示例:

服务端(server.c):

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

#define SERVER_IP "127.0.0.1"
#define SERVER_PORT 8080
#define BUFFER_SIZE 1024

int main() {
    int serverSocket;
    struct sockaddr_in serverAddr, clientAddr;
    socklen_t clientAddrLen;
    char buffer[BUFFER_SIZE];

    // 创建服务端套接字
    serverSocket = socket(AF_INET, SOCK_DGRAM, 0);
    if (serverSocket == -1) {
        perror("Failed to create socket");
        exit(EXIT_FAILURE);
    }

    // 设置服务器地址信息
    memset(&serverAddr, 0, sizeof(serverAddr));
    serverAddr.sin_family = AF_INET;
    serverAddr.sin_port = htons(SERVER_PORT);
    serverAddr.sin_addr.s_addr = htonl(INADDR_ANY);

    // 绑定套接字到指定地址和端口
    if (bind(serverSocket, (struct sockaddr *)&serverAddr, sizeof(serverAddr)) == -1) {
        perror("Failed to bind socket");
        exit(EXIT_FAILURE);
    }

    printf("Server listening on port %d...\n", SERVER_PORT);

    // 接收数据
    clientAddrLen = sizeof(clientAddr);
    memset(buffer, 0, sizeof(buffer));
    if (recvfrom(serverSocket, buffer, BUFFER_SIZE, 0, (struct sockaddr *)&clientAddr, &clientAddrLen) == -1) {
        perror("Failed to receive data");
        exit(EXIT_FAILURE);
    }

    printf("Client message: %s\n", buffer);

    // 发送响应
    strcpy(buffer, "Hello, Client!");
    if (sendto(serverSocket, buffer, strlen(buffer), 0, (struct sockaddr *)&clientAddr, clientAddrLen) == -1) {
        perror("Failed to send data");
        exit(EXIT_FAILURE);
    }

    // 关闭套接字
    close(serverSocket);

    return 0;
}

客户端(client.c):

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

#define SERVER_IP "127.0.0.1"
#define SERVER_PORT 8080
#define BUFFER_SIZE 1024

int main() {
    int clientSocket;
    struct sockaddr_in serverAddr;
    char buffer[BUFFER_SIZE];

    // 创建客户端套接字


    clientSocket = socket(AF_INET, SOCK_DGRAM, 0);
    if (clientSocket == -1) {
        perror("Failed to create socket");
        exit(EXIT_FAILURE);
    }

    // 设置服务器地址信息
    memset(&serverAddr, 0, sizeof(serverAddr));
    serverAddr.sin_family = AF_INET;
    serverAddr.sin_port = htons(SERVER_PORT);
    if (inet_pton(AF_INET, SERVER_IP, &(serverAddr.sin_addr)) <= 0) {
        perror("Failed to set server IP");
        exit(EXIT_FAILURE);
    }

    printf("Connected to server %s:%d\n", SERVER_IP, SERVER_PORT);

    // 发送数据
    strcpy(buffer, "Hello, Server!");
    if (sendto(clientSocket, buffer, strlen(buffer), 0, (struct sockaddr *)&serverAddr, sizeof(serverAddr)) == -1) {
        perror("Failed to send data");
        exit(EXIT_FAILURE);
    }

    // 接收响应
    memset(buffer, 0, sizeof(buffer));
    if (recvfrom(clientSocket, buffer, BUFFER_SIZE, 0, NULL, NULL) == -1) {
        perror("Failed to receive data");
        exit(EXIT_FAILURE);
    }

    printf("Server response: %s\n", buffer);

    // 关闭套接字
    close(clientSocket);

    return 0;
}

这些示例代码分别实现了TCP和UDP的服务端和客户端通信。你可以根据需要进行编译并运行这些代码,它们将在本地主机上创建一个套接字连接,通过网络进行通信。TCP是面向连接的可靠传输协议,而UDP是面向无连接的不可靠传输协议,它们在使用上有一些区别。

TCP相对于UDP具有以下特点:

  • TCP提供可靠的、面向连接的通信,确保数据的准确传输和顺序交付。
  • TCP使用三次握手建立连接,并通过应答机制进行数据的确认和重传,保证数据的可靠性。
  • TCP具有拥塞控制和流量控制的机制,能够根据网络情况动态调整发送速率,防止网络拥塞。
  • TCP适用于对数据准确性要求高、顺序要求严格的应用场景,如文件传输、网页浏览等。

UDP相对于TCP具有以下特点:

  • UDP是无连接的通信协议,发送方将数据以数据包的形式发送给接收方,没有建立和维护连接的过程。
  • UDP不提供数据的可靠性和顺序交付,发送方将数据包发送给接收方后不会进行确认和重传操作。
  • UDP具有较低的延迟和较小的开销,适用于对实时性要求较高、对数据准确性要求相对较低的应用场景,如实时视频、音频传输等。

通过这些示例代码,你可以了解如何使用C语言通过Socket实现TCP和UDP的通信,并了解到TCP和UDP在使用上的差异和

适用场景。你可以根据需要对代码进行修改和扩展,实现更复杂的功能和应用。

总结:
Socket编程是网络编程中的重要技术,通过Socket可以实现不同主机之间的数据通信。本篇博客介绍了Socket编程的基本概念和原理,以及通过一个简单的聊天应用示例展示了其实际应用。深入理解和掌握Socket编程将有助于嵌入式开发者在网络通信领域取得更好的成果。

引用:Linux的SOCKET编程详解文章来源地址https://www.toymoban.com/news/detail-620283.html

到了这里,关于Socket编程详解:从基本概念到实例应用(TCP|UDP C语言实例详解)的文章就介绍完了。如果您还想了解更多内容,请在右上角搜索TOY模板网以前的文章或继续浏览下面的相关文章,希望大家以后多多支持TOY模板网!

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

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

相关文章

  • Java——TCP UDP Socket编程

    目录 一、网络的相关概念 (一)网络通信 (二)网络 (三)ip地址 (四)ipv4地址分类 (五)域名 (六)网络通信协议 (七)TCP和UDP 二、InetAddress类 三、Socket 四、TCP网络编程 (一)案例一——使用字节流 (二)案例二——使用字节流  (三)案例三——使用字符流 (四

    2024年02月06日
    浏览(43)
  • socket的基本使用,基于TCP/UDP

    OSI参考模型 Open System Interconnect 开放式系统 每层网络的由来 物理层:010101比特流,设备之间原始数据的传输,数模转换(发送端)和模数转换(接收端) -》传输过程可能出现错码和误码? 数据链路层:将原始比特流转换成逻辑传输符号,提供纠错编码,格式变为帧 -》出现

    2024年02月03日
    浏览(39)
  • Python使用 Twisted 实现 TCP/UDP Socket 编程

    更多文章: 技数未来 环境准备: - 安装Python:确保你已经安装了Python解释器。 - 安装Twisted:可以通过pip命令来安装Twisted库,运行`pip install twisted`即可。 依赖的类库: - twisted.internet.protocol:包含了实现TCP/UDP Socket编程所需的协议类。 - twisted.internet.reactor:用于处理事件循环

    2024年02月16日
    浏览(48)
  • Socket套接字编程(实现TCP和UDP的通信)

      🎉🎉🎉点进来你就是我的人了 博主主页:🙈🙈🙈戳一戳,欢迎大佬指点! 人生格言: 当你的才华撑不起你的野心的时候,你就应该静下心来学习! 欢迎志同道合的朋友一起加油喔 🦾🦾🦾 目标梦想:进大厂,立志成为一个牛掰的Java程序猿,虽然现在还是一个🐒嘿嘿 谢谢

    2024年02月03日
    浏览(91)
  • Java网络编程基础:TCP Socket套接字编程 IntAddress UDP等...

    目录 一,网络基础 1.IP地址 2.端口 3.TCP/UDP协议 4.网络编程开发模式  二,基于套接字的Java网络编程 1.Socket  2.InetAddress 三.基于TCP的Socket网络编程 1.单服务器端与单Socket客户端一次通讯 2.单服务器端接收多次通讯  3.TCP网络通讯补充 四,基于UDP的网络编程 1. DatagramSocket:收发

    2024年04月29日
    浏览(45)
  • 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日
    浏览(60)
  • Java网络编程(二)Socket 套接字(TCP和UDP),以及TCP的回显

    我们软件工作者,着重编写的是应用层的代码,但是发送这个数据,我们就需要将应用层传输到传输层,也就意味着我们需要调用应用层的API,统称为 Socket API。 套接字的分类: 流套接字:使用传输层TCP协议 特点: 有连接:使用 TCP 通信的双方,需要时刻保存对方的相关消

    2024年02月09日
    浏览(53)
  • 网络:从socket编程的角度说明UDP和TCP的关系,http和tcp的区别

             尝试从编程的角度解释各种网络协议。         从Python的socket编程角度出发,UDP( User Datagram Protocol )和TCP( Transmission Control Protocol )是两种不同的传输协议。 TCP是一种面向连接的协议,提供可靠的、有序的、双向的数据传输。在TCP中,客户端和服务器之间

    2024年02月14日
    浏览(38)
  • Java中的网络编程------基于Socket的TCP编程和基于UDP的网络编程,netstat指令

    Socket 在Java中,Socket是一种用于网络通信的编程接口, 它允许不同计算机之间的程序进行数据交换和通信 。Socket使得网络应用程序能够通过TCP或UDP协议在不同主机之间建立连接、发送数据和接收数据。以下是Socket的基本介绍: Socket类型 :在Java中,有两种主要类型的Socket,分

    2024年02月10日
    浏览(39)
  • python3套接字编程之socket和socketserver(TCP和UDP通信)

    socket和socketserver是python3中socket通信模块,关于其使用做如下总结。 目录 1.socket 1.1模块引入 1.2套接字获取 1.3套接字接口 1.3.1 服务端 1.3.2 客户端套接字函数 1.3.3 公共套接字函数 1.3.4 面向锁的套接字方法 1.3.5 面向文件的套接字的函数 2.socketserver 3.TCP 3.1 socket类型TCP 3.2 sockets

    2024年02月15日
    浏览(75)

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

支付宝扫一扫打赏

博客赞助

微信扫一扫打赏

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

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

二维码1

领取红包

二维码2

领红包