欢迎光临
我们一直在努力

c 网络编程教程

C语言网络编程基础

C语言在网络编程领域具有重要地位,其高效性和灵活性使其成为实现网络通信的常用语言,网络编程主要涉及套接字(Socket)的使用,通过套接字可以实现不同主机上的进程间通信。

套接字编程基础

1、创建套接字:使用socket()函数创建一个套接字,该函数需要指定协议族、套接字类型和协议参数,创建一个TCP套接字的代码如下:

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

AF_INET表示IPv4协议族,SOCK_STREAM表示面向连接的流式套接字。

2、绑定地址:将套接字与本地的一个地址(IP地址和端口号)绑定起来,通常用于服务器端,使用bind()函数实现,示例代码如下:

   struct sockaddr_in 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("Bind failed");
       close(sockfd);
       exit(EXIT_FAILURE);
   }

这里将套接字绑定到所有可用的接口上,并指定了端口号。

3、监听连接请求:对于TCP服务器,需要调用listen()函数来监听客户端的连接请求。

   if (listen(sockfd, 5) < 0) {
       perror("Listen failed");
       close(sockfd);
       exit(EXIT_FAILURE);
   }

第二个参数指定了最大监听队列长度。

4、接受连接:当有客户端尝试连接服务器时,服务器使用accept()函数接受连接,并创建一个新的套接字用于与客户端通信,示例代码如下:

   struct sockaddr_in cli_addr;
   socklen_t clilen = sizeof(cli_addr);
   int connfd = accept(sockfd, (struct sockaddr *)&cli_addr, &clilen);
   if (connfd < 0) {
       perror("Accept failed");
       close(sockfd);
       exit(EXIT_FAILURE);
   }

5、发送和接收数据:建立连接后,可以使用send()recv()函数进行数据的发送和接收。

   char buffer[BUFFER_SIZE];
   ssize_t bytes_sent = send(connfd, buffer, strlen(buffer), 0);
   if (bytes_sent < 0) {
       perror("Send failed");
       close(connfd);
       exit(EXIT_FAILURE);
   }
   ssize_t bytes_received = recv(connfd, buffer, sizeof(buffer), 0);
   if (bytes_received < 0) {
       perror("Receive failed");
       close(connfd);
       exit(EXIT_FAILURE);
   }

6、关闭套接字:当不再需要使用套接字时,应使用close()函数及时关闭它,以释放资源。

   close(connfd);
   close(sockfd);

网络协议相关知识

1、TCP协议:提供可靠的、有序的、无差错的数据传输服务,它适用于需要高可靠性的网络应用,如文件传输、电子邮件等,在TCP通信中,数据会被分成适当长度的报文段进行传输,并确保每个报文段都能正确到达接收方且按序排列。

2、UDP协议:一个简单的面向数据报的传输层协议,不提供可靠性保证,但传输速度较快,它适用于对实时性要求较高但对数据准确性要求相对较低的应用,如视频流、在线游戏等。

多线程编程在网络编程中的应用

在实际应用中,服务器通常需要处理多个客户端的连接请求,为了提高并发性能,可以使用多线程编程,在C语言中,可以使用pthread库来创建和管理线程。

   pthread_t thread_id;
   pthread_create(&thread_id, NULL, handle_client, (void *)&newsockfd);
   pthread_detach(thread_id);

这样可以为每个客户端连接创建一个新的线程来处理,提高服务器的响应能力。

示例代码:简单的TCP服务器和客户端

以下是一个简单的TCP服务器和客户端示例:

1、TCP服务器

   #include <stdio.h>
   #include <stdlib.h>
   #include <string.h>
   #include <unistd.h>
   #include <arpa/inet.h>
   #include <pthread.h>
   #define PORT 8080
   void *handle_client(void *arg) {
       int sockfd = *(int *)arg;
       char buffer[1024];
       int n;
       while ((n = recv(sockfd, buffer, sizeof(buffer), 0)) > 0) {
           send(sockfd, buffer, n, 0);
       }
       close(sockfd);
       return NULL;
   }
   int main() {
       int server_fd, new_socket;
       struct sockaddr_in address;
       int addrlen = sizeof(address);
       if ((server_fd = socket(AF_INET, SOCK_STREAM, 0)) == 0) {
           perror("Socket creation failed");
           exit(EXIT_FAILURE);
       }
       address.sin_family = AF_INET;
       address.sin_addr.s_addr = INADDR_ANY;
       address.sin_port = htons(PORT);
       if (bind(server_fd, (struct sockaddr *)&address, sizeof(address)) < 0) {
           perror("Bind failed");
           close(server_fd);
           exit(EXIT_FAILURE);
       }
       if (listen(server_fd, 3) < 0) {
           perror("Listen failed");
           close(server_fd);
           exit(EXIT_FAILURE);
       }
       while (1) {
           if ((new_socket = accept(server_fd, (struct sockaddr *)&address, (socklen_t*)&addrlen)) < 0) {
               perror("Accept failed");
               continue;
           }
           pthread_t thread_id;
           pthread_create(&thread_id, NULL, handle_client, (void *)&new_socket);
           pthread_detach(thread_id);
       }
       close(server_fd);
       return 0;
   }

2、TCP客户端

   #include <stdio.h>
   #include <stdlib.h>
   #include <string.h>
   #include <unistd.h>
   #include <arpa/inet.h>
   #define PORT 8080
   int main() {
       int sock = 0;
       struct sockaddr_in serv_addr;
       char *message = "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);
       if (inet_pton(AF_INET, "127.0.0.1", &serv_addr.sin_addr) <= 0) {
           printf("
Invalid address
");
           return -1;
       }
       if (connect(sock, (struct sockaddr *)&serv_addr, sizeof(serv_addr)) < 0) {
           printf("
Connection failed
");
           return -1;
       }
       send(sock, message, strlen(message), 0);
       printf("Hello message sent
");
       return 0;
   }
未经允许不得转载:九八云安全 » c 网络编程教程