如何区分C语言中的客户端与服务器端?

客户端与服务器端是计算机网络中的两个基本概念,分别指代不同的计算设备或程序。

在网络编程中,客户端和服务器端的交互是构建分布式系统的基础,使用C语言进行网络编程时,通常会涉及到套接字(socket)的使用,这是一种进程间通信的方式,下面将详细介绍如何使用C语言编写一个简单的客户端和服务器端程序。

如何区分C语言中的客户端与服务器端?

服务端程序

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、绑定套接字:需要将套接字绑定到一个特定的端口号和IP地址,可以使用bind()函数来完成这个操作:

   struct sockaddr_in address;
   address.sin_family = AF_INET;
   address.sin_addr.s_addr = INADDR_ANY;
   address.sin_port = htons(PORT);
   if (bind(server_socket, (struct sockaddr *)&address, sizeof(address)) < 0) {
       perror("bind failed");
       close(server_socket);
       exit(EXIT_FAILURE);
   }

3、监听连接请求:绑定成功后,服务器需要开始监听来自客户端的连接请求,可以使用listen()函数来实现:

   if (listen(server_socket, 3) < 0) {
       perror("listen failed");
       close(server_socket);
       exit(EXIT_FAILURE);
   }

4、接受连接请求:当有客户端连接请求时,服务器需要接受这个请求,并创建一个新的套接字来与客户端通信,可以使用accept()函数来实现:

如何区分C语言中的客户端与服务器端?

   int addrlen = sizeof(address);
   int new_socket = accept(server_socket, (struct sockaddr *)&address, (socklen_t*)&addrlen);
   if (new_socket < 0) {
       perror("accept failed");
       close(server_socket);
       exit(EXIT_FAILURE);
   }

5、处理数据传输:服务器端可以使用read()和write()函数来接收和发送数据,以下是一个简单的例子,服务器接收客户端发送的数据并回传给客户端:

   char buffer[1024] = {0};
   int valread = read(new_socket, buffer, 1024);
   printf("Received: %s
", buffer);
   write(new_socket, buffer, strlen(buffer));

客户端程序

1、创建套接字:客户端也需要创建一个套接字,使用方法与服务器端相同:

   int client_socket = socket(AF_INET, SOCK_STREAM, 0);
   if (client_socket < 0) {
       perror("socket failed");
       exit(EXIT_FAILURE);
   }

2、连接到服务器:客户端需要连接到指定的服务器IP地址和端口号,可以使用connect()函数来实现:

   struct sockaddr_in serv_addr;
   serv_addr.sin_family = AF_INET;
   serv_addr.sin_port = htons(PORT);
   if (inet_pton(AF_INET, "127.0.0.1", &serv_addr.sin_addr) <= 0) {
       perror("Invalid address or address not supported");
       close(client_socket);
       exit(EXIT_FAILURE);
   }
   if (connect(client_socket, (struct sockaddr *)&serv_addr, sizeof(serv_addr)) < 0) {
       perror("Connection failed");
       close(client_socket);
       exit(EXIT_FAILURE);
   }

3、处理数据传输:客户端可以使用send()和recv()函数来发送和接收数据,以下是一个简单的例子,客户端发送数据到服务器并接收服务器的回传数据:

   char *message = "Hello, Server!";
   send(client_socket, message, strlen(message), 0);
   printf("Message sent
");
   char buffer[1024] = {0};
   int valread = recv(client_socket, buffer, 1024, 0);
   printf("Received: %s
", buffer);

错误处理

在网络编程中,错误处理是非常重要的,需要确保在每个系统调用之后检查返回值,并在出现错误时进行适当的处理。

如何区分C语言中的客户端与服务器端?

if (server_socket < 0) {
    perror("socket failed");
    exit(EXIT_FAILURE);
}

完整示例代码

服务器端代码

#include <stdio.h>
#include <stdlib.h>
#include <string.h>
#include <unistd.h>
#include <arpa/inet.h>
#define PORT 8080
int main() {
    int server_fd, new_socket;
    struct sockaddr_in address;
    int opt = 1;
    int addrlen = sizeof(address);
      
    // Creating socket file descriptor
    if ((server_fd = socket(AF_INET, SOCK_STREAM, 0)) == 0) {
        perror("socket failed");
        exit(EXIT_FAILURE);
    }
      
    // Forcefully attaching socket to the port 8080
    if (setsockopt(server_fd, SOL_SOCKET, SO_REUSEADDR | SO_REUSEPORT, &opt, sizeof(opt))) {
        perror("setsockopt");
        exit(EXIT_FAILURE);
    }
    address.sin_family = AF_INET;
    address.sin_addr.s_addr = INADDR_ANY;
    address.sin_port = htons(PORT);
      
    // Forcefully attaching socket to the port 8080
    if (bind(server_fd, (struct sockaddr *)&address, sizeof(address))<0) {
        perror("bind failed");
        exit(EXIT_FAILURE);
    }
    if (listen(server_fd, 3) < 0) {
        perror("listen");
        exit(EXIT_FAILURE);
    }
    if ((new_socket = accept(server_fd, (struct sockaddr *)&address, (socklen_t*)&addrlen))<0) {
        perror("accept");
        exit(EXIT_FAILURE);
    }
      
    char buffer[1024] = {0};
    int valread = read(new_socket, buffer, 1024);
    printf("%s
",buffer);
    send(new_socket, buffer, strlen(buffer), 0);
    printf("Hello from server
");
    return 0;
}

客户端代码

#include <stdio.h>
#include <sys/socket.h>
#include <arpa/inet.h>
#include <unistd.h>
#include <string.h>
#define PORT 8080
int main() {
    int sock = 0;
    struct sockaddr_in serv_addr;
    char *hello = "Hello from client";
    char buffer[1024] = {0};
    if ((sock = socket(AF_INET, SOCK_STREAM, 0)) < 0) {
        printf("
 Socket creation error 
");
        return -1;
    }
  
    serv_addr.sin_family = AF_INET;
    serv_addr.sin_port = htons(PORT);
      
    // Convert IPv4 and IPv6 addresses from text to binary form
    if(inet_pton(AF_INET, "127.0.0.1", &serv_addr.sin_addr)<=0) {
        printf("
Invalid address/ Address not supported 
");
        return -1;
    }
  
    if (connect(sock, (struct sockaddr *)&serv_addr, sizeof(serv_addr)) < 0) {
        printf("
Connection Failed 
");
        return -1;
    }
    send(sock, hello, strlen(hello), 0);
    printf("Hello message sent
");
    valread = read(sock, buffer, 1024);
    printf("%s
",buffer);
    return 0;
}

原创文章,作者:未希,如若转载,请注明出处:https://www.kdun.com/ask/1489936.html

本网站发布或转载的文章及图片均来自网络,其原创性以及文中表达的观点和判断不代表本网站。如有问题,请联系客服处理。

(0)
未希
上一篇 2025-01-15 05:39
下一篇 2024-11-21 07:29

相关推荐

  • 如何在C中实现跨服务器文件传输?

    在C#中,跨服务器传输文件可以通过多种方式实现,例如使用FTP、HTTP或直接通过Socket编程。以下是一个使用FTP的简单示例:,,“csharp,using System;,using System.IO;,using System.Net;,,class Program,{, static void Main(), {, string ftpServer = “ftp://example.com”;, string username = “yourUsername”;, string password = “yourPassword”;, string filePath = @”C:\path\to\your\file.txt”;, string uploadUri = ftpServer + “/upload/file.txt”;,, FtpWebRequest request = (FtpWebRequest)WebRequest.Create(uploadUri);, request.Method = WebRequestMethods.Ftp.UploadFile;, request.Credentials = new NetworkCredential(username, password);,, byte[] fileContents;, using (StreamReader sourceStream = new StreamReader(filePath)), {, fileContents = Encoding.UTF8.GetBytes(sourceStream.ReadToEnd());, }, request.ContentLength = fileContents.Length;,, using (Stream requestStream = request.GetRequestStream()), {, requestStream.Write(fileContents, 0, fileContents.Length);, },, using (FtpWebResponse response = (FtpWebResponse)request.GetResponse()), {, Console.WriteLine($”Upload File Complete, status {response.StatusDescription}”);, }, },},“,,这个示例展示了如何使用FTP协议将本地文件上传到远程服务器。请根据实际情况修改FTP服务器地址、用户名、密码和文件路径。

    2025-01-15
    06
  • 如何在C中访问需要登录的网站?

    在C#中访问需要登录的网站,可以使用HttpClient类来发送POST请求,包括用户名和密码的表单数据,从而模拟登录过程。

    2025-01-15
    06
  • 如何在Linux中使用C语言实现毫秒级的计时?

    在 Linux 系统中,可以使用 date 命令加上 +%s%3N 格式化选项来获取当前时间的毫秒数。运行 date +%s%3N 会返回自 Unix 纪元(1970-01-01 00:00:00 UTC)以来的秒数和毫秒数。

    2025-01-15
    05
  • 如何在C中查询数据库?

    在 C# 中,可以使用 SqlConnection 和 SqlCommand 来查询数据库。

    2025-01-15
    00

发表回复

您的电子邮箱地址不会被公开。 必填项已用 * 标注

产品购买 QQ咨询 微信咨询 SEO优化
分享本页
返回顶部
云产品限时秒杀。精选云产品高防服务器,20M大带宽限量抢购 >>点击进入