目录
前言
服务器程序
服务器程序验证过程
客户端程序
前言
驱动开发暂时告一段落了。后面在研究一下OLED和GPS的驱动开发,并且优化前面已经移植过来的这些驱动,我的理念是在封装个逻辑处理层来处理这些驱动程序。server直接操作逻辑处理层的程序。
这次服务器的开发也不会一步到位,先做最简单的然后在逐渐迭代。
服务器程序
/*
* 文件名: server.c
* 作者: 辛天宇
* 更新时间: 2024-04-10
* 软件版本号: 0.0.0
*/
/**************************************************************
***************************INCLUDE*****************************
**************************************************************/
#include "net.h"
/**************************************************************
****************************LOCAL******************************
**************************************************************/
void cli_data_handle (void *arg);
int main()
{
int fd = -1;
struct sockaddr_in sin;
//创建socket fd*
if((fd = socket(AF_INET,SOCK_STREAM, 0)) < 0){
perror("socket");
//return -1;
exit(1);
}
/*优化4: 允许绑定地址快速重用 */
int b_reuse = 1;
setsockopt (fd, SOL_SOCKET, SO_REUSEADDR, &b_reuse, sizeof (int));
//绑定
//填充struct socketddr_in结构体变量
bzero(&sin,sizeof(sin));//把sin全填充0
sin.sin_family = AF_INET;//地址族网际网区域
sin.sin_port = htons(SERV_PORT); //网络字节端口号
//优化使server可以绑定在任意IP上
#if 1
sin.sin_addr.s_addr = htonl(INADDR_ANY);//INADDY_ANY = -1
#else
if( inet_pton(AF_INET,SERV_IP_ADDR,(void *)&sin.sin_addr) != 1){
perror("inet_pton");
exit(1);
}
#endif
//绑定
if(bind(fd, (struct sockaddr *)&sin, sizeof(sin)) < 0) {
perror("bind");
exit(1);
}
//调用listen()把主动套接字变成被动套接字
if(listen(fd,BACKLOG) < 0 ){
perror("listen");
exit(1);
}
printf("Server starting...OK!\n");
int newfd = -1;
//阻塞等待客户端连接
#if 0
newfd = accept(fd, NULL, NULL);
if(newfd < 0){
perror("accept");
exit(1);
}
#else
//通过程序获取刚建立连接的socket客户端的ip地址和端口号
pthread_t tid;
struct sockaddr_in cin;
socklen_t addrlen = sizeof (cin);
while (1) {
if ((newfd = accept (fd, (struct sockaddr *) &cin, &addrlen)) < 0) {
perror ("accept");
exit (1);
}
char ipv4_addr[16];
if (!inet_ntop (AF_INET, (void *) &cin.sin_addr, ipv4_addr, sizeof (cin))) {
perror ("inet_ntop");
exit (1);
}
printf ("Clinet(%s:%d) is connected!\n", ipv4_addr, htons (cin.sin_port));
pthread_create (&tid, NULL, (void *) cli_data_handle, (void *) &newfd);
}
close (fd);
return 0;
}
#endif
void cli_data_handle (void *arg)
{
int newfd = *(int *) arg;
printf ("handler thread: newfd =%d\n", newfd);
//..和newfd进行数据读写
int ret = -1;
char buf[BUFSIZ];
while (1) {
bzero (buf, BUFSIZ);
do {
ret = read (newfd, buf, BUFSIZ - 1);
} while (ret < 0 && EINTR == errno);
if (ret < 0) {
perror ("read");
exit (1);
}
if (!ret) { //对方已经关闭
break;
}
printf ("Receive data: %s\n", buf);
if (!strncasecmp (buf, QUIT_STR, strlen (QUIT_STR))) { //用户输入了quit字符
printf ("Client(fd=%d) is exiting!\n", newfd);
break;
}
}
close (newfd);
}
这是以前学网络编程的时候写的拿过来改一改
稍微改一下
/*
*author : xintianyu
*function : main
*data : 2024-4-10
-----------------------
*author : ???
*return : ???
*data : ???
*/
int main(int argc, char *argv[])
{
if(ERROR == usage(argc, argv))
return 0;
tcp_server(argc, argv);
return 0;
}
/*
*author : xintianyu
*return : err num
*data : 2024-4-10
-----------------------
*author : ???
*return : ???
*data : ???
*/
int usage(int argc, char *argv[])
{
if (argc != 3)
{
printf("Usage: %s <ip_address> <port>\n", argv[0]);
return ERROR;
}
else
{
return NOERROR;
}
}
/*
*author : xintianyu
*return : err num
*data : 2024-4-10
-----------------------
*author : ???
*return : ???
*data : ???
*/
int tcp_server(int argc, char *argv[])
{
int server_fd, client_fd;
struct sockaddr_in server_addr, client_addr;
socklen_t client_len = sizeof(client_addr);
char buffer[BUFFER_SIZE];
char *ip_address = argv[1];
int port = atoi(argv[2]);
// 创建TCP套接字
if ((server_fd = socket(AF_INET, SOCK_STREAM, 0)) == -1) {
perror("socket creation failed");
exit(EXIT_FAILURE);
}
// 设置服务器地址信息
memset(&server_addr, 0, sizeof(server_addr));
server_addr.sin_family = AF_INET;
server_addr.sin_addr.s_addr = inet_addr(ip_address);
server_addr.sin_port = htons(port);
// 绑定套接字到服务器地址
if (bind(server_fd, (struct sockaddr *)&server_addr, sizeof(server_addr)) < 0) {
perror("bind failed");
exit(EXIT_FAILURE);
}
// 监听套接字
if (listen(server_fd, 5) < 0) {
perror("listen failed");
exit(EXIT_FAILURE);
}
printf("Server listening on %s:%d...\n", ip_address, port);
while (1) {
// 接受客户端连接
if ((client_fd = accept(server_fd, (struct sockaddr *)&client_addr, &client_len)) < 0) {
perror("accept failed");
continue;
}
// 打印客户端信息
char client_ip[INET_ADDRSTRLEN];
inet_ntop(AF_INET, &client_addr.sin_addr, client_ip, INET_ADDRSTRLEN);
printf("Client connected from %s:%d\n", client_ip, ntohs(client_addr.sin_port));
// 接收客户端消息
memset(buffer, 0, BUFFER_SIZE);
ssize_t bytes_read = recv(client_fd, buffer, BUFFER_SIZE - 1, 0);
if (bytes_read < 0) {
perror("recv failed");
close(client_fd);
continue;
}
// 确保消息以换行符结尾,并打印接收到的消息
if (bytes_read > 0 && buffer[bytes_read - 1] != '\n') {
buffer[bytes_read] = '\n';
buffer[bytes_read + 1] = '\0';
}
printf("Received message: %s", buffer);
// 回复客户端消息
strcpy(buffer, "Hello, client!\n");
if (send(client_fd, buffer, strlen(buffer), 0) < 0) {
perror("send failed");
}
close(client_fd);
}
close(server_fd);
return NOERROR;
}
写的比较简单因为没有业务逻辑暂时只是验证通信问题。
服务器程序验证过程
编译命令
这是我们现在的目录结构
客户端程序
import socket
server_ip = '192.168.5.110'
server_port = 8888
# 设置服务器地址和端口
server_address = (server_ip, server_port)
# 创建一个socket对象
client_socket = socket.socket(socket.AF_INET, socket.SOCK_STREAM)
# 连接到服务器
client_socket.connect(server_address)
try:
# 发送数据
message = 'Hello, server!'.encode()
print(f'Sending {message}')
client_socket.sendall(message)
# 接收数据
amount_received = 0
amount_expected = len(message)
while amount_received < amount_expected:
data = client_socket.recv(16)
amount_received += len(data)
print(f'Received {data}')
finally:
# 关闭连接
print('Closing socket')
client_socket.close()
一下就没了我优化一下让他可以一直通信
import socket
server_ip = '192.168.5.110'
server_port = 8888
# 设置服务器地址和端口
server_address = (server_ip, server_port)
# 创建一个socket对象
client_socket = socket.socket(socket.AF_INET, socket.SOCK_STREAM)
# 连接到服务器
try:
client_socket.connect(server_address)
print(f'Connected to {server_address}')
# 接收用户输入并发送给服务器
while True:
try:
user_input = input('Enter command (or "exit" to quit): ')
if user_input.lower() == 'exit':
break
client_socket.sendall(user_input.encode())
# 接收服务器的响应
data = client_socket.recv(1024)
print(f'Received: {data.decode()}')
except KeyboardInterrupt:
print('\nKeyboardInterrupt received, exiting...')
break
except ConnectionResetError:
print('\nConnection reset by server, exiting...')
break
except Exception as e:
print(f'An error occurred: {e}, trying to reconnect...')
client_socket.close() # Close the socket if there's an error
client_socket = socket.socket(socket.AF_INET, socket.SOCK_STREAM) # Create a new one
client_socket.connect(server_address) # Reconnect to the server
finally:
# 关闭连接
print('Closing socket')
client_socket.close()
有问题哇,只能发过去第一条
一顿debug发现是服务器的问题,现在算是通讯正常了。
服务器最新程序
int tcp_server(int argc, char *argv[])
{
int server_fd, client_fd;
struct sockaddr_in server_addr, client_addr;
socklen_t client_len = sizeof(client_addr);
char buffer[BUFFER_SIZE];
char *ip_address = argv[1];
int port = atoi(argv[2]);
// 创建TCP套接字
if ((server_fd = socket(AF_INET, SOCK_STREAM, 0)) == -1) {
perror("socket creation failed");
exit(EXIT_FAILURE);
}
// 设置服务器地址信息
memset(&server_addr, 0, sizeof(server_addr));
server_addr.sin_family = AF_INET;
server_addr.sin_addr.s_addr = inet_addr(ip_address);
server_addr.sin_port = htons(port);
// 绑定套接字到服务器地址
if (bind(server_fd, (struct sockaddr *)&server_addr, sizeof(server_addr)) < 0) {
perror("bind failed");
exit(EXIT_FAILURE);
}
// 监听套接字
if (listen(server_fd, 5) < 0) {
perror("listen failed");
exit(EXIT_FAILURE);
}
printf("Server listening on %s:%d...\n", ip_address, port);
// 接受客户端连接
if ((client_fd = accept(server_fd, (struct sockaddr *)&client_addr, &client_len)) < 0) {
perror("accept failed");
}
while (1)
{
// 打印客户端信息
char client_ip[INET_ADDRSTRLEN];
inet_ntop(AF_INET, &client_addr.sin_addr, client_ip, INET_ADDRSTRLEN);
printf("Client connected from %s:%d\n", client_ip, ntohs(client_addr.sin_port));
// 接收客户端消息
memset(buffer, 0, BUFFER_SIZE);
ssize_t bytes_read = recv(client_fd, buffer, BUFFER_SIZE - 1, 0);
if (bytes_read < 0) {
perror("recv failed");
close(client_fd);
continue;
}
// 确保消息以换行符结尾,并打印接收到的消息
if (bytes_read > 0 && buffer[bytes_read - 1] != '\n') {
buffer[bytes_read] = '\n';
buffer[bytes_read + 1] = '\0';
}
printf("Received message: %s", buffer);
// 回复客户端消息
strcpy(buffer, "Hello, client!\n");
if (send(client_fd, buffer, strlen(buffer), 0) < 0)
{
perror("send failed");
}
}
close(client_fd);
close(server_fd);
return NOERROR;
}