C语言编写基于TCP和UDP协议的Socket通信程序示例

下面我来为你详细讲解“C语言编写基于TCP和UDP协议的Socket通信程序示例”的攻略。

一、Socket简介

Socket(套接字)是一种应用程序编程接口(API),也是一种通信协议,用于在计算机网络上实现进程间通信和数据传输。Socket可以用于不同操作系统之间、不同应用程序之间、不同计算机之间的通信。

二、基于TCP协议的Socket通信

1. 创建Socket和服务器绑定

使用socket函数创建Socket,bind函数将创建的Socket与服务器的IP地址和端口绑定:

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

#define PORT 8888

int main(int argc, char const *argv[])
{
    int sock = 0, valread;
    struct sockaddr_in serv_addr;
    char *hello = "Hello from client";
    char buffer[1024] = {0};

    // 创建Socket
    if ((sock = socket(AF_INET, SOCK_STREAM, 0)) < 0)
    {
        printf("\n Socket creation error \n");
        return -1;
    }

    memset(&serv_addr, '0', sizeof(serv_addr));

    // 设置服务器地址族
    serv_addr.sin_family = AF_INET;
    serv_addr.sin_port = htons(PORT);

    // 将Ipv4地址从点分十进制转换为网络字节序
    if(inet_pton(AF_INET, "127.0.0.1", &serv_addr.sin_addr)<=0)
    {
        printf("\nInvalid address/ Address not supported \n");
        return -1;
    }

    // 将创建的Socket绑定到服务器地址和端口
    if (connect(sock, (struct sockaddr *)&serv_addr, sizeof(serv_addr)) < 0)
    {
        printf("\nConnection Failed \n");
        return -1;
    }

    send(sock , hello , strlen(hello) , 0 );
    printf("Hello message sent\n");
    valread = read( sock , buffer, 1024);
    printf("%s\n",buffer );
    return 0;
}

2. 监听客户端连接请求

使用listen函数监听客户端的连接请求:

if (listen(server_fd, 3) < 0)
{
    perror("listen");
    exit(EXIT_FAILURE);
}

3. 处理客户端连接请求

使用accept函数处理客户端的连接请求,创建一个新的Socket来与客户端通信,最后关闭Socket:

while(1)
{
    if ((new_socket = accept(server_fd, (struct sockaddr *)&address, (socklen_t*)&addrlen))<0)
    {
        perror("accept");
        exit(EXIT_FAILURE);
    }

    valread = read( new_socket , buffer, 1024);
    printf("%s\n",buffer );
    send(new_socket , hello , strlen(hello) , 0 );
    printf("Hello message sent\n");
    close(new_socket);
}

三、基于UDP协议的Socket通信

1. 创建Socket和服务器绑定

使用socket函数创建Socket,并使用bind函数将Socket和服务器的IP地址和端口绑定:

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

#define PORT 8888

int main() {
    int sockfd;
    struct sockaddr_in servaddr, cliaddr;

    // 创建Socket
    if ( (sockfd = socket(AF_INET, SOCK_DGRAM, 0)) < 0 ) {
        perror("socket creation failed");
        exit(EXIT_FAILURE);
    }

    memset(&servaddr, 0, sizeof(servaddr));
    memset(&cliaddr, 0, sizeof(cliaddr));

    // 设置服务器地址族
    servaddr.sin_family = AF_INET;
    servaddr.sin_addr.s_addr = INADDR_ANY;
    servaddr.sin_port = htons(PORT);

    // 将创建的Socket绑定到服务器地址和端口
    if ( bind(sockfd, (const struct sockaddr *)&servaddr, sizeof(servaddr)) < 0 ) {
        perror("bind failed");
        exit(EXIT_FAILURE);
    }

    // 接受客户端的数据
    int len, n;
    len = sizeof(cliaddr);
    char buffer[1024] = {0};
    n = recvfrom(sockfd, (char *)buffer, 1024, MSG_WAITALL, ( struct sockaddr *) &cliaddr, &len);
    buffer[n] = '\0';
    printf("Client : %s\n", buffer);

    // 给客户端发送回应信号
    char *hello = "Hello from server";
    sendto(sockfd, (const char *)hello, strlen(hello), MSG_CONFIRM, (const struct sockaddr *) &cliaddr, len);
    printf("Hello message sent.\n");

    return 0;
}

2. 向服务器发送数据

创建客户端Socket后,向服务器发送数据:

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

#define PORT 8888

int main(int argc, char const *argv[])
{
    int sockfd;
    char buffer[1024] = {0};
    char *hello = "Hello from client";
    struct sockaddr_in servaddr;

    // 创建客户端Socket
    if ( (sockfd = socket(AF_INET, SOCK_DGRAM, 0)) < 0 ) {
        perror("Socket creation failed.\n");
        exit(EXIT_FAILURE);
    }

    memset(&servaddr, 0, sizeof(servaddr));

    // 设置服务器地址族
    servaddr.sin_family = AF_INET;
    servaddr.sin_port = htons(PORT);
    servaddr.sin_addr.s_addr = INADDR_ANY;

    int n, len;
    len = sizeof(servaddr);

    // 向服务器发送信息
    sendto(sockfd, (const char *)hello, strlen(hello), MSG_CONFIRM, (const struct sockaddr *) &servaddr, len);
    printf("Hello message sent.\n");

    // 等待服务器回应
    n = recvfrom(sockfd, (char *)buffer, 1024, MSG_WAITALL, (struct sockaddr *) &servaddr, &len);
    buffer[n] = '\0';
    printf("Server : %s\n", buffer);

    close(sockfd);
    return 0;
}

这就是基于TCP和UDP协议的Socket通信程序示例攻略的详细讲解,希望对你有所帮助。

本站文章如无特殊说明,均为本站原创,如若转载,请注明出处:C语言编写基于TCP和UDP协议的Socket通信程序示例 - Python技术站

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

相关文章

  • C++ 中构造函数的实例详解

    C++ 中构造函数的实例详解 什么是构造函数 在 C++ 中,构造函数是一个特殊的函数,用于在对象被创建时进行初始化的操作。每个类都必须拥有至少一个构造函数,否则编译器将会自动为其创建一个默认构造函数。 构造函数的定义和调用 构造函数与普通函数类似,也有参数和函数体,但是它没有返回值和函数名称与类名相同。构造函数在创建对象时自动调用。 class MyCla…

    C 2023年5月22日
    00
  • C语言错误使用解引操作

    C语言错误使用解引操作的完整使用攻略 什么是解引操作 解引操作是指使用指针变量获取指针变量所指向地址上存储的数据。在 C 语言中,我们使用 * 进行解引操作,例如: int a = 100; int *p = &a; int b = *p; // 这里的 *p 就是解引操作,将 p 指向的地址上的值赋值给 b 错误使用解引操作的问题 错误使用解引操作…

    C 2023年5月9日
    00
  • 如何修改MYSQL5.7.17数据库存储文件的路径

    以下是具体的攻略,分为以下几个步骤: 1. 关闭MySQL数据库 在开始修改MySQL数据库存储文件的路径之前,需要先关闭MySQL数据库,具体操作可以参照以下命令: sudo /etc/init.d/mysql stop 2. 复制原存储文件内容 在进行路径修改之前,需要先将原来的存储文件内容复制到将要修改的路径下,具体操作可以参照以下命令: sudo c…

    C 2023年5月23日
    00
  • 基于C++编写一个键盘提示音程序

    关于基于C++编写一个键盘提示音程序的攻略,我将为您提供以下完整的指导: 步骤一:了解键盘输入的基础知识 在编写键盘提示音的程序之前,我们需要了解一些基础概念: 键盘布局:键盘上每一个按键的位置; 扫描码:键盘上每一个按键都有一个与之对应的扫描码,用于唯一地识别每一个按键; ASCII码:每一个扫描码都对应了一个ASCII码,用于标示按键所对应的字符。 步骤…

    C 2023年5月23日
    00
  • 神乐千鹤在拳皇97、98中的高级用法

    神乐千鹤在拳皇97、98中的高级用法攻略 什么是神乐千鹤? 神乐千鹤是拳皇系列游戏中的一位角色,拥有快速的移动速度和敏捷的攻击方式。她在拳皇97和98中的操作难度较高,但是如果掌握了她的高级用法,就可以轻松地击败对手。 神乐千鹤的高级用法 1. 投掷连击 神乐千鹤的投掷连击是一种非常强大的攻击方式。要进行投掷连击,首先需要进行一次投掷攻击(按下前+C),然后…

    C 2023年5月22日
    00
  • C语言详解如何应用模拟字符串和内存函数

    C语言是一门广泛应用于系统编程和算法实现的编程语言。其中,模拟字符串和内存函数常常被用于字符串和数据处理。本攻略将详细讲解如何在C语言中实现模拟字符串和内存函数,以及如何应用它们解决实际问题。 一、字符串的模拟 1.1. 什么是字符串 在C语言中,字符串是一个由字符组成的数组,以’\0’结尾。例如,”hello world”是一个字符串,它实际上是一个包含1…

    C 2023年5月23日
    00
  • C++ 实现LRU 与 LFU 的缓存算法

    C++ 实现LRU 与 LFU 的缓存算法 算法描述 LRU和LFU是常用的缓存算法。它们能够优化系统读写速度,提高系统效率。 LRU LRU (Least Recent Used)是最近最少使用算法,维护一个缓存队列,每次访问缓存中的一个元素时,将其移动到队列的头部,当缓存队列满时删除队尾元素,保证最近使用过的元素在缓存队列的最前面,最近没有使用过的元素在…

    C 2023年5月22日
    00
  • 详解C++11 线程休眠函数

    详解C++11 线程休眠函数 在C++11中,新增了一个<chrono>头文件,其中包含了许多与时间相关的类和函数。其中,std::this_thread::sleep_for是一个非常实用的函数,它可以让当前线程休眠一段时间。 函数原型 namespace std { namespace chrono { template<class R…

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