欢迎访问宙启技术站
智能推送

C++中Socket网络编程实例详解

发布时间:2023-05-18 03:09:45

Socket是一种封装了TCP/IP协议的编程接口,常用于网络编程中。在C语言中,使用Socket进行网络编程可以极大地扩展程序的功能。下面我们将介绍一个简单的Socket网络编程实例,帮助读者了解Socket网络编程的基本使用方法。

1. 创建Socket

在C语言中,可以使用socket函数创建一个Socket,函数定义如下:

#include <sys/socket.h>

int socket(int domain, int type, int protocol);

其中,domain参数指定Socket的协议族,type参数指定Socket的类型,protocol参数指定所使用的协议。常用的协议族有AF_INET(IPv4)和AF_INET6(IPv6),常用的Socket类型有SOCK_STREAM(面向连接的套接字)和SOCK_DGRAM(无连接套接字),常用的协议有TCP和UDP。

下面是一个创建TCP的Socket的示例代码:

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

#define PORT 12345

int main(int argc, char **argv)
{
  int sockfd;
  struct sockaddr_in serv_addr;

  sockfd = socket(AF_INET, SOCK_STREAM, 0);
  if (sockfd < 0)
  {
    perror("ERROR opening socket");
    exit(1);
  }

  memset(&serv_addr, 0, sizeof(serv_addr));
  serv_addr.sin_family = AF_INET;
  serv_addr.sin_addr.s_addr = htonl(INADDR_ANY);
  serv_addr.sin_port = htons(PORT);

  if (bind(sockfd, (struct sockaddr *)&serv_addr, sizeof(serv_addr)) < 0)
  {
    perror("ERROR on binding");
    exit(1);
  }

  listen(sockfd, 5);

  return 0;
}

在这个例子中,我们使用socket函数创建了一个TCP的Socket,并将其绑定到本地的一个端口上。listen函数则将这个Socket置于监听状态,以便随时能够接收来自客户端的请求。

2. 接收客户端请求

当服务器程序启动并开始监听后,就可以接收来自客户端的请求了。在C语言中,使用accept函数接收客户端的连接请求,函数定义如下:

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

int accept(int sockfd, struct sockaddr *addr, socklen_t *addrlen);

其中,sockfd参数是监听Socket的文件描述符,addr参数是用于存放客户端地址信息的结构体指针,addrlen参数则是addr结构体的大小。

接下来是一个简单的Socket服务器程序的示例代码,程序运行后会一直在等待客户端请求:

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

#define PORT 12345

int main(int argc, char **argv)
{
  int sockfd, newsockfd;
  socklen_t clilen;
  struct sockaddr_in serv_addr, cli_addr;

  sockfd = socket(AF_INET, SOCK_STREAM, 0);
  if (sockfd < 0) 
  {
    perror("ERROR opening socket");
    exit(1);
  }

  memset(&serv_addr, 0, sizeof(serv_addr));
  serv_addr.sin_family = AF_INET;
  serv_addr.sin_addr.s_addr = htonl(INADDR_ANY);
  serv_addr.sin_port = htons(PORT);

  if (bind(sockfd, (struct sockaddr *)&serv_addr, sizeof(serv_addr)) < 0)
  {
    perror("ERROR on binding");
    exit(1);
  }

  listen(sockfd, 5);
  clilen = sizeof(cli_addr);

  while (1)
  {
    newsockfd = accept(sockfd, (struct sockaddr *)&cli_addr, &clilen);
    if (newsockfd < 0)
    {
      perror("ERROR on accept");
      exit(1);
    }

    /* Do something with the new client connected */

    close(newsockfd);
  }

  return 0;
}

3. 向客户端发送数据

在Socket网络编程中,服务器程序可以通过向客户端发送数据来处理客户端请求。在C语言中,可以使用send函数向客户端发送数据,函数定义如下:

#include <sys/types.h>
#include <sys/socket.h>

ssize_t send(int sockfd, const void *buf, size_t len, int flags);

其中,sockfd参数是Socket的文件描述符,buf参数是发送数据的缓冲区,len参数是缓冲区中要发送的数据的长度,flags参数则指定传输时的各种选项,一般默认为0。

下面是一个简单的实例,向客户端发送一条Hello World消息:

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

#define PORT 12345

int main(int argc, char **argv)
{
  int sockfd, newsockfd;
  socklen_t clilen;
  struct sockaddr_in serv_addr, cli_addr;
  char *message = "Hello World!";

  sockfd = socket(AF_INET, SOCK_STREAM, 0);
  if (sockfd < 0) 
  {
    perror("ERROR opening socket");
    exit(1);
  }

  memset(&serv_addr, 0, sizeof(serv_addr));
  serv_addr.sin_family = AF_INET;
  serv_addr.sin_addr.s_addr = htonl(INADDR_ANY);
  serv_addr.sin_port = htons(PORT);

  if (bind(sockfd, (struct sockaddr *)&serv_addr, sizeof(serv_addr)) < 0)
  {
    perror("ERROR on binding");
    exit(1);
  }

  listen(sockfd, 5);
  clilen = sizeof(cli_addr);

  while (1)
  {
    newsockfd = accept(sockfd, (struct sockaddr *)&cli_addr, &clilen);
    if (newsockfd < 0)
    {
      perror("ERROR on accept");
      exit(1);
    }

    send(newsockfd, message, strlen(message), 0);

    close(newsockfd);
  }

  return 0;
}

4. 接收客户端数据

当服务器向客户端发送了数据后,客户端也可以向服务器发送数据。在C语言中,可以使用recv函数接收客户端传来的数据,函数定义如下:

#include <sys/types.h>
#include <sys/socket.h>

ssize_t recv(int sockfd, void *buf, size_t len, int flags);

其中,sockfd参数是Socket的文件描述符,buf参数是接收数据的缓冲区,len参数是缓冲区的长度,flags则是传输选项,一般默认为0。

下面是一个简单的实例,接收来自客户端的一条消息:

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

#define PORT 12345

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

  sockfd = socket(AF_INET, SOCK_STREAM, 0);
  if (sockfd < 0) 
  {
    perror("ERROR opening socket");
    exit(1);
  }

  memset(&serv_addr, 0, sizeof(serv_addr));
  serv_addr.sin_family = AF_INET;
  serv_addr.sin_addr.s_addr = htonl(INADDR_ANY);
  serv_addr.sin_port = htons(PORT);

  if (bind(sockfd, (struct sockaddr *)&serv_addr, sizeof(serv_addr)) < 0)
  {
    perror("ERROR on binding");
    exit(1);
  }

  listen(sockfd, 5);
  clilen = sizeof(cli_addr);

  while (1)
  {
    newsockfd = accept(sockfd, (struct sockaddr *)&cli_addr, &clilen);
    if (newsockfd < 0)
    {
      perror("ERROR on accept");
      exit(1);
    }

    memset(buffer, 0, sizeof(buffer));
    n = recv(newsockfd, buffer, sizeof(buffer), 0);
    if (n < 0)
    {
      perror("ERROR reading from socket");
      exit(1);
    }

    printf("Message from client: %s
", buffer);

    close(newsockfd);
  }

  return 0;
}

通过读取来自客户端的传输,服务器可以进一步对请求进行处理。

总结

本文介绍了C语言中Socket网络编程的一些基础知识,包括创建Socket、接收客户端请求、向客户端发送数据和接收客户端数据等操作。Socket网络编程可以极大地扩展程序的功能,可以应用于网络通信、文件