新编C语言SOCKET编程指南.pdf
### 新编C语言SOCKET编程指南 #### 一、引言 在计算机网络通信领域,Socket编程是一项核心技能。无论是开发互联网应用还是局域网工具,掌握Socket编程都是必不可少的。本文档旨在为初学者提供一份详尽的C语言Socket编程指南。 #### 二、Socket简介 **1. 什么是Socket?** Socket是一种用于进程间通信的机制,它允许不同进程之间通过网络进行数据交换。在Unix/Linux系统中,Socket被设计成类似于文件的操作接口,开发者可以通过标准的文件描述符API来进行网络通信。 **2. Socket的工作原理** - **文件描述符:** Socket通过一个整数型的文件描述符来标识。 - **创建Socket:** 使用`socket()`函数创建一个Socket。 - **绑定与监听:** 通过`bind()`函数将Socket与特定端口绑定,然后使用`listen()`函数使Socket处于监听状态。 - **接受连接:** 使用`accept()`函数等待客户端连接。 - **数据传输:** 使用`send()`和`recv()`函数进行数据的发送和接收。 - **关闭Socket:** 最后使用`close()`或`shutdown()`函数关闭Socket。 #### 三、Internet套接字的两种类型 **1. Stream Sockets (SOCK_STREAM)** - **定义:** 流式套接字提供可靠、有序、无差错的数据传输。 - **用途:** 主要用于需要高可靠性的应用,如Telnet、FTP等。 - **特点:** 数据不会丢失,也不会重复,而且按照发送顺序接收。 **2. Datagram Sockets (SOCK_DGRAM)** - **定义:** 数据报套接字提供不可靠、无序、无差错的数据传输。 - **用途:** 适用于不要求数据可靠传输的应用,如DNS查询、SNMP协议等。 - **特点:** 数据可能会丢失或重复,且不一定按发送顺序到达。 #### 四、网络理论基础 - **协议栈:** TCP/IP协议栈是Internet的基础,包括网络层、传输层、应用层等多个层次。 - **IP地址:** 用于唯一标识网络中的设备。 - **端口号:** 用于区分同一台主机上的不同服务。 - **TCP/UDP:** TCP提供面向连接的服务,而UDP提供无连接的服务。 #### 五、关键函数解析 **1. socket()函数** - **功能:** 创建一个新的Socket。 - **参数:** 家族(AF_INET、AF_UNIX等)、类型(SOCK_STREAM、SOCK_DGRAM等)、协议(通常为0)。 - **返回值:** 成功时返回一个非负的Socket描述符,失败时返回-1。 **2. bind()函数** - **功能:** 将Socket绑定到指定的地址和端口。 - **参数:** Socket描述符、地址结构体指针、地址长度。 - **返回值:** 成功时返回0,失败时返回-1。 **3. connect()函数** - **功能:** 建立到远程主机的连接。 - **参数:** Socket描述符、地址结构体指针、地址长度。 - **返回值:** 成功时返回0,失败时返回-1。 **4. listen()函数** - **功能:** 将Socket设置为监听模式。 - **参数:** Socket描述符、待连接队列的最大长度。 - **返回值:** 成功时返回0,失败时返回-1。 **5. accept()函数** - **功能:** 接受来自客户端的连接请求。 - **参数:** 监听状态的Socket描述符、地址结构体指针、地址长度指针。 - **返回值:** 成功时返回新的Socket描述符,失败时返回-1。 **6. send()和recv()函数** - **功能:** 分别用于发送和接收数据。 - **参数:** Socket描述符、缓冲区指针、缓冲区长度、标志。 - **返回值:** 成功时返回实际发送或接收的字节数,失败时返回-1。 **7. close()和shutdown()函数** - **功能:** 关闭Socket。 - **参数:** Socket描述符。 - **返回值:** 成功时返回0,失败时返回-1。 #### 六、示例代码分析 为了更好地理解Socket编程的过程,下面给出两个简单的示例:一个是服务器端,另一个是客户端。 **1. 简单服务器端代码** ```c #include <stdio.h> #include <stdlib.h> #include <string.h> #include <unistd.h> #include <sys/types.h> #include <sys/socket.h> #include <netinet/in.h> int main(int argc, char *argv[]) { int server_socket, new_socket, valread; struct sockaddr_in address; int opt = 1; int addrlen = sizeof(address); char buffer[1024] = {0}; char* hello = "Hello from server"; // Creating socket file descriptor if ((server_socket = socket(AF_INET, SOCK_STREAM, 0)) == 0) { perror("socket failed"); exit(EXIT_FAILURE); } // Forcefully attaching socket to the port 8080 if (setsockopt(server_socket, 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( 8080 ); // Forcefully attaching socket to the port 8080 if (bind(server_socket, (struct sockaddr *)&address, sizeof(address))<0) { perror("bind failed"); exit(EXIT_FAILURE); } // Listen for up to 3 connections if (listen(server_socket, 3) < 0) { perror("listen"); exit(EXIT_FAILURE); } // Accept connection if ((new_socket = accept(server_socket, (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"); return 0; } ``` **2. 简单客户端代码** ```c #include <stdio.h> #include <stdlib.h> #include <string.h> #include <unistd.h> #include <sys/types.h> #include <sys/socket.h> #include <netinet/in.h> #include <arpa/inet.h> int main(int argc, char *argv[]) { int sock = 0, valread; struct sockaddr_in serv_addr; char *hello = "Hello from client"; char buffer[1024] = {0}; // Creating socket file descriptor if ((sock = socket(AF_INET, SOCK_STREAM, 0)) < 0) { printf("\n Socket creation error \n"); return -1; } serv_addr.sin_family = AF_INET; serv_addr.sin_port = htons(8080); // 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("\nInvalid address/ Address not supported \n"); return -1; } 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; } ``` #### 七、结论 本文档提供了C语言Socket编程的基本知识和技术要点,通过阅读本文档,读者可以了解到Socket编程的基本概念、主要函数及其用法,以及如何实现简单的客户端和服务器程序。Socket编程是网络通信的基础,对于希望从事网络编程工作的开发者来说,熟练掌握这一技术是非常重要的。
剩余20页未读,继续阅读
- 粉丝: 1
- 资源: 10
- 我的内容管理 展开
- 我的资源 快来上传第一个资源
- 我的收益 登录查看自己的收益
- 我的积分 登录查看自己的积分
- 我的C币 登录后查看C币余额
- 我的收藏
- 我的下载
- 下载帮助