Val编程-套接字

本文介绍了套接字编程的基础知识,包括客户端与服务器的工作原理、配置方法及注意事项。通过实例演示了如何创建简单的内环连接,并提供了配置文件的示例。

摘要生成于 C知道 ,由 DeepSeek-R1 满血版支持, 前往体验 >

套接字的介绍:http://zh.wikipedia.org/wiki/Berkeley%E5%A5%97%E6%8E%A5%E5%AD%97
主要分为客户端和服务器。客户端一般是需要主动去链接,需要配置服务器的IP和端口。服务器是被动响应,需要打开相应的端口。端口一般不推荐使用系统端口和常用软件使用端口。
可以使用socket模拟器来练习编程。可以使用SocketTool,可以到百度网盘下载。http://pan.baidu.com/share/link?shareid=430046&uk=2080830206.免安装,直接可以使用。一般推荐使用Tcp(暂不推荐使用UDP)。

分别创建客户端和服务器。下面是一个利用127.0.0.1建立内环的一个例子。服务器建立以后需要进行监听(listen)

机械手臂控制器配置:
控制面板(Control panel)->输入输出(I/O)->套接字(Socket)有服务器(Servers)和客户端(Clients)

进行服务器和客户端配置。
                                                                         

其相对应的配置文件在/usr/configs/sio.cfx
内容为:

在Val3 studio里按下F1,可以得到Val3的说明手册。里面有对Sio类型的详细解释。

  

常见问题分析与总结:

1.服务器与客户端打开顺序无关
2.CS8C服务器不能获知是否与模拟器客户端连接,客户端也不知
3.利用clearBuff来激活CS8C的服务器
4.运行CS8C的应用程序,客户端会主动激活。sent或者receive都是主动连接。
5.关闭CS8C的应用程序,服务器与客户端会关闭
6.有时客户端连接不到CS8C的服务器的问题分析。

                    

程序模拟:

     

### 3.1 套接字接口编程概述 套接字(Socket)是网络编程的基础,用于不同主机上的应用程序之间进行数据交换。它提供了一个统一的接口,使得开发者可以基于标准的系统调用构建网络通信程序。套接字的概念最早由 Unix 系统引入,并逐渐成为现代网络编程的核心机制之一[^1]。 在编程中,套接字接口提供了多种基本操作,包括创建、绑定、连接、监听、发送和接收数据等。这些操作构成了网络通信的核心流程,适用于 TCP 和 UDP 协议。例如,TCP 通信通常涉及服务器端的监听和客户端的连接,而 UDP 通信则更偏向于无连接的数据报传输[^2]。 ### 3.2 套接字基本操作与函数调用 创建套接字通常使用 `socket()` 系统调用,该函数返回一个描述符,后续操作均基于该描述符进行。创建成功后,若为服务器端程序,需调用 `bind()` 将套接字绑定到特定的 IP 地址和端口,以接收来自客户端的连接请求。对于 TCP 服务,还需调用 `listen()` 启动监听模式,并通过 `accept()` 接收客户端连接请求,建立新的通信套接字。客户端则通过 `connect()` 主动发起连接。 在数据传输阶段,TCP 使用 `send()` 和 `recv()` 进行流式数据发送与接收,而 UDP 则使用 `sendto()` 和 `recvfrom()`,因为其通信是无连接的,每次发送或接收都需要指定目标或来源地址[^3]。 ### 3.3 套接字地址结构与通用接口设计 套接字函数如 `connect()`、`bind()` 和 `accept()` 都需要一个指向特定协议地址结构的指针。为了实现接口的通用性,C 语言中采用 `struct sockaddr` 作为通用结构体指针,应用程序需将具体协议的地址结构强制转换为该类型。例如,IPv4 地址使用 `struct sockaddr_in`,而 IPv6 使用 `struct sockaddr_in6`,它们都可被转换为 `struct sockaddr` 传入系统调用中[^5]。 绑定地址时,`bind()` 函数需要三个参数:套接字描述符、地址结构指针和结构体长度。若绑定失败,函数返回 -1,并可通过 `errno` 获取错误信息[^4]。 ### 3.4 TCP 通信编程示例 以下是一个基于 C 语言的 TCP 服务器端与客户端通信的简单示例: #### TCP 服务器端代码 ```c #include <sys/types.h> #include <sys/socket.h> #include <netinet/in.h> #include <unistd.h> #include <stdio.h> #include <string.h> int main() { int server_fd, new_socket; struct sockaddr_in address; int addrlen = sizeof(address); char buffer[1024] = {0}; const char *response = "Hello from server"; // 创建套接字 server_fd = socket(AF_INET, SOCK_STREAM, 0); if (server_fd == -1) { perror("Socket creation failed"); return -1; } // 绑定地址和端口 address.sin_family = AF_INET; address.sin_addr.s_addr = INADDR_ANY; address.sin_port = htons(8080); if (bind(server_fd, (struct sockaddr *)&address, sizeof(address)) < 0) { perror("Bind failed"); return -1; } // 监听连接 listen(server_fd, 3); printf("Server listening on port 8080\n"); // 接受连接 new_socket = accept(server_fd, (struct sockaddr *)&address, (socklen_t*)&addrlen); if (new_socket < 0) { perror("Accept failed"); return -1; } // 接收数据 int valread = read(new_socket, buffer, 1024); printf("Received: %s\n", buffer); // 发送响应 send(new_socket, response, strlen(response), 0); printf("Response sent\n"); // 关闭套接字 close(new_socket); close(server_fd); return 0; } ``` #### TCP 客户端代码 ```c #include <sys/types.h> #include <sys/socket.h> #include <netinet/in.h> #include <unistd.h> #include <stdio.h> #include <string.h> int main() { int sock = 0; struct sockaddr_in serv_addr; char buffer[1024] = {0}; const char *message = "Hello from client"; // 创建套接字 sock = socket(AF_INET, SOCK_STREAM, 0); if (sock == -1) { perror("Socket creation failed"); return -1; } // 设置服务器地址 serv_addr.sin_family = AF_INET; serv_addr.sin_port = htons(8080); serv_addr.sin_addr.s_addr = inet_addr("127.0.0.1"); // 连接服务器 if (connect(sock, (struct sockaddr *)&serv_addr, sizeof(serv_addr)) < 0) { perror("Connection failed"); return -1; } // 发送数据 send(sock, message, strlen(message), 0); printf("Message sent\n"); // 接收响应 int valread = read(sock, buffer, 1024); printf("Received: %s\n", buffer); // 关闭套接字 close(sock); return 0; } ``` ### 3.5 UDP 通信编程示例 UDP 是无连接协议,因此其编程流程相对简单,无需建立连接即可发送和接收数据。 #### UDP 服务器端代码 ```c #include <sys/types.h> #include <sys/socket.h> #include <netinet/in.h> #include <unistd.h> #include <stdio.h> #include <string.h> int main() { int sockfd; struct sockaddr_in servaddr, cliaddr; socklen_t len = sizeof(cliaddr); char buffer[1024]; // 创建套接字 sockfd = socket(AF_INET, SOCK_DGRAM, 0); if (sockfd == -1) { perror("Socket creation failed"); return -1; } // 绑定地址 memset(&servaddr, 0, sizeof(servaddr)); servaddr.sin_family = AF_INET; servaddr.sin_addr.s_addr = INADDR_ANY; servaddr.sin_port = htons(8080); if (bind(sockfd, (const struct sockaddr *)&servaddr, sizeof(servaddr)) < 0) { perror("Bind failed"); return -1; } // 接收数据 int n = recvfrom(sockfd, (char *)buffer, sizeof(buffer), 0, (struct sockaddr *)&cliaddr, &len); buffer[n] = '\0'; printf("Received: %s\n", buffer); // 发送响应 const char *response = "Hello from UDP server"; sendto(sockfd, response, strlen(response), 0, (const struct sockaddr *)&cliaddr, len); printf("Response sent\n"); close(sockfd); return 0; } ``` #### UDP 客户端代码 ```c #include <sys/types.h> #include <sys/socket.h> #include <netinet/in.h> #include <unistd.h> #include <stdio.h> #include <string.h> int main() { int sockfd; struct sockaddr_in servaddr; char buffer[1024]; // 创建套接字 sockfd = socket(AF_INET, SOCK_DGRAM, 0); if (sockfd == -1) { perror("Socket creation failed"); return -1; } // 设置服务器地址 memset(&servaddr, 0, sizeof(servaddr)); servaddr.sin_family = AF_INET; servaddr.sin_port = htons(8080); servaddr.sin_addr.s_addr = inet_addr("127.0.0.1"); // 发送数据 const char *message = "Hello from UDP client"; sendto(sockfd, message, strlen(message), 0, (const struct sockaddr *)&servaddr, sizeof(servaddr)); printf("Message sent\n"); // 接收响应 socklen_t len = sizeof(servaddr); int n = recvfrom(sockfd, (char *)buffer, sizeof(buffer), 0, (struct sockaddr *)&servaddr, &len); buffer[n] = '\0'; printf("Received: %s\n", buffer); close(sockfd); return 0; } ``` ###
评论 3
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值