size=sizeof(String1); //开始存储 for(j=0;j<6;j++) TEXT_Buffer[j]=String1[count1][j]; STMFLASH_Write(FLASH_SAVE_ADDR+(2*count1*SIZE),(u16*)TEXT_Buffer,SIZE);
时间: 2024-04-20 10:23:34 浏览: 53
这段代码是将`String1`数组中的字符串存储到闪存中的函数代码片段。首先,通过`sizeof(String1)`获取`String1`数组的大小,并将结果赋值给变量`size`。然后,使用循环将`String1`数组中指定索引`count1`对应的字符串的前6个字符赋值给`TEXT_Buffer`数组。最后,调用`STMFLASH_Write`函数将`TEXT_Buffer`数组中的数据写入到闪存的指定地址中。其中,`FLASH_SAVE_ADDR+(2*count1*SIZE)`表示闪存中的存储地址,`(u16*)TEXT_Buffer`表示要写入的数据指针,`SIZE`表示要写入的数据大小。
相关问题
用linux编写有P1,P2,P3三个进程,P1和P2负责从键盘接收字符串,均发送给P3,P3接收到字符串,根据发送方分别显示”P3 received *** from P1(或P2)" ;分别用管道通信,消息队列和共享存储三种通信方式实现。
以下是使用管道通信实现的代码:
```c
#include <stdio.h>
#include <stdlib.h>
#include <unistd.h>
#include <string.h>
#include <sys/types.h>
#include <sys/wait.h>
#define BUFFER_SIZE 1024
int main() {
int pipe1[2], pipe2[2], pid1, pid2;
char buffer[BUFFER_SIZE];
if (pipe(pipe1) == -1) {
perror("pipe1 failed");
exit(EXIT_FAILURE);
}
if (pipe(pipe2) == -1) {
perror("pipe2 failed");
exit(EXIT_FAILURE);
}
if ((pid1 = fork()) == -1) {
perror("fork pid1 failed");
exit(EXIT_FAILURE);
}
if (pid1 == 0) {
// Child Process P1
close(pipe1[0]);
close(pipe2[0]);
close(pipe2[1]);
while (1) {
printf("Enter a string (P1): ");
fgets(buffer, BUFFER_SIZE, stdin);
buffer[strlen(buffer) - 1] = '\0'; // Remove newline character
write(pipe1[1], buffer, strlen(buffer) + 1);
}
close(pipe1[1]);
} else {
if ((pid2 = fork()) == -1) {
perror("fork pid2 failed");
exit(EXIT_FAILURE);
}
if (pid2 == 0) {
// Child Process P2
close(pipe1[0]);
close(pipe1[1]);
close(pipe2[0]);
while (1) {
printf("Enter a string (P2): ");
fgets(buffer, BUFFER_SIZE, stdin);
buffer[strlen(buffer) - 1] = '\0'; // Remove newline character
write(pipe2[1], buffer, strlen(buffer) + 1);
}
close(pipe2[1]);
} else {
// Parent Process P3
close(pipe1[1]);
close(pipe2[1]);
while (1) {
fd_set read_set;
FD_ZERO(&read_set);
FD_SET(pipe1[0], &read_set);
FD_SET(pipe2[0], &read_set);
select(FD_SETSIZE, &read_set, NULL, NULL, NULL);
if (FD_ISSET(pipe1[0], &read_set)) {
read(pipe1[0], buffer, BUFFER_SIZE);
printf("P3 received %s from P1\n", buffer);
}
if (FD_ISSET(pipe2[0], &read_set)) {
read(pipe2[0], buffer, BUFFER_SIZE);
printf("P3 received %s from P2\n", buffer);
}
}
close(pipe1[0]);
close(pipe2[0]);
}
}
return 0;
}
```
以下是使用消息队列实现的代码:
```c
#include <stdio.h>
#include <stdlib.h>
#include <unistd.h>
#include <string.h>
#include <sys/types.h>
#include <sys/ipc.h>
#include <sys/msg.h>
#define BUFFER_SIZE 1024
struct message {
long type;
char text[BUFFER_SIZE];
};
int main() {
int msgid, pid1, pid2;
struct message msg;
key_t key = ftok(".", 'a');
if ((msgid = msgget(key, 0666 | IPC_CREAT)) == -1) {
perror("msgget failed");
exit(EXIT_FAILURE);
}
if ((pid1 = fork()) == -1) {
perror("fork pid1 failed");
exit(EXIT_FAILURE);
}
if (pid1 == 0) {
// Child Process P1
while (1) {
printf("Enter a string (P1): ");
fgets(msg.text, BUFFER_SIZE, stdin);
msg.text[strlen(msg.text) - 1] = '\0'; // Remove newline character
msg.type = 1;
msgsnd(msgid, &msg, strlen(msg.text) + 1, 0);
}
} else {
if ((pid2 = fork()) == -1) {
perror("fork pid2 failed");
exit(EXIT_FAILURE);
}
if (pid2 == 0) {
// Child Process P2
while (1) {
printf("Enter a string (P2): ");
fgets(msg.text, BUFFER_SIZE, stdin);
msg.text[strlen(msg.text) - 1] = '\0'; // Remove newline character
msg.type = 2;
msgsnd(msgid, &msg, strlen(msg.text) + 1, 0);
}
} else {
// Parent Process P3
while (1) {
msgrcv(msgid, &msg, BUFFER_SIZE, 0, 0);
if (msg.type == 1) {
printf("P3 received %s from P1\n", msg.text);
} else if (msg.type == 2) {
printf("P3 received %s from P2\n", msg.text);
}
}
msgctl(msgid, IPC_RMID, NULL);
}
}
return 0;
}
```
以下是使用共享存储实现的代码:
```c
#include <stdio.h>
#include <stdlib.h>
#include <unistd.h>
#include <string.h>
#include <sys/types.h>
#include <sys/ipc.h>
#include <sys/shm.h>
#define BUFFER_SIZE 1024
struct shared_memory {
char text[BUFFER_SIZE];
};
int main() {
int shmid, pid1, pid2;
struct shared_memory *shm;
key_t key = ftok(".", 'a');
if ((shmid = shmget(key, sizeof(struct shared_memory), 0666 | IPC_CREAT)) == -1) {
perror("shmget failed");
exit(EXIT_FAILURE);
}
if ((shm = (struct shared_memory *) shmat(shmid, NULL, 0)) == (struct shared_memory *) -1) {
perror("shmat failed");
exit(EXIT_FAILURE);
}
if ((pid1 = fork()) == -1) {
perror("fork pid1 failed");
exit(EXIT_FAILURE);
}
if (pid1 == 0) {
// Child Process P1
while (1) {
printf("Enter a string (P1): ");
fgets(shm->text, BUFFER_SIZE, stdin);
shm->text[strlen(shm->text) - 1] = '\0'; // Remove newline character
printf("P1 wrote: %s\n", shm->text);
}
} else {
if ((pid2 = fork()) == -1) {
perror("fork pid2 failed");
exit(EXIT_FAILURE);
}
if (pid2 == 0) {
// Child Process P2
while (1) {
printf("Enter a string (P2): ");
fgets(shm->text, BUFFER_SIZE, stdin);
shm->text[strlen(shm->text) - 1] = '\0'; // Remove newline character
printf("P2 wrote: %s\n", shm->text);
}
} else {
// Parent Process P3
while (1) {
sleep(1); // Wait for P1 or P2 to write
if (strlen(shm->text) != 0) {
if (strstr(shm->text, "P1") != NULL) {
printf("P3 received %s from P1\n", shm->text);
} else if (strstr(shm->text, "P2") != NULL) {
printf("P3 received %s from P2\n", shm->text);
}
shm->text[0] = '\0'; // Clear shared memory
}
}
shmdt(shm);
shmctl(shmid, IPC_RMID, NULL);
}
}
return 0;
}
```
注意:由于共享内存是多个进程都可以访问的,因此在使用共享内存时需要注意同步和互斥问题,例如使用信号量等机制。上述代码简单地使用了 sleep 函数来等待 P1 或 P2 写入数据。
使用c语言,在不改变原有功能的基础上添加txt文件,使客户端能选择传送普通数据还是txt文件
要在现有的C语言代码基础上实现客户端可以选择传送普通数据还是TXT文件的功能,可以通过在客户端增加一个选项来选择传输模式(普通数据或文件)。以下是修改后的代码示例:
### 服务器端代码 (`server.c`)
```c
#define DEFAULT_PORT 5050 // 服务端的默认端口号为 5050
#define BUFFER_SIZE 1024 // 缓冲区大小
#define _WINSOCK_DEPRECATED_NO_WARNINGS // 忽略 Winsock 过时警告
#include <stdio.h>
#include <string.h>
#include <winsock2.h>
#include <ws2tcpip.h>
#include <process.h> // 添加这个头文件以使用 _beginthreadex
#pragma comment(lib, "ws2_32.lib") // 告诉编译器链接 Winsock 库
unsigned __stdcall thread_func(void* lpThreadParameter)
{
SOCKET s_client = *(SOCKET*)lpThreadParameter; // 从参数中获取客户端套接字
free(lpThreadParameter);
while (1){
// 读取传输模式
char mode[BUFFER_SIZE] = {0};
int ret = recv(s_client, mode, BUFFER_SIZE, 0);
if (ret <= 0) break;
if (strcmp(mode, "text") == 0) {
// 接收普通文本数据
char buffer[BUFFER_SIZE] = {0};
ret = recv(s_client, buffer, BUFFER_SIZE, 0);
if (ret <= 0) break;
printf("TCP Server Receive: %s\n", buffer);
send(s_client, buffer, (int)strlen(buffer), 0);
printf("TCP Server Send: %s\n", buffer);
} else if (strcmp(mode, "file") == 0) {
// 接收文件
char filename[BUFFER_SIZE] = {0};
ret = recv(s_client, filename, BUFFER_SIZE, 0);
if (ret <= 0) break;
FILE *fp = fopen(filename, "wb");
if (!fp) {
printf("Failed to create file.\n");
continue;
}
while (1) {
char buffer[BUFFER_SIZE] = {0};
ret = recv(s_client, buffer, BUFFER_SIZE, 0);
if (ret <= 0) break;
fwrite(buffer, 1, ret, fp);
if (ret < BUFFER_SIZE) break; // 文件传输结束
}
fclose(fp);
printf("File received and saved as %s\n", filename);
} else {
printf("Unknown mode: %s\n", mode);
}
}
printf("客户端: %llu 断开连接.\n", s_client); // 打印客户端断开连接的信息。
closesocket(s_client); // 关闭客户端套接字。
_endthreadex(0); // 结束线程
return 0;
}
int main(int argc, char *argv[])
{
int iPort = DEFAULT_PORT;
// 初始化 Winsock 库,版本为 2.2。
WSADATA wsaData;
if (WSAStartup(MAKEWORD(2, 2), &wsaData) != 0)
{
printf("Failed to load Winsock.\n");
return -1;
}
// 1. 创建一个 IPv4 的流式套接字。
SOCKET s_listen = socket(AF_INET, SOCK_STREAM, 0);
if (s_listen == INVALID_SOCKET)
{
printf("socket() Failed: %d\n", WSAGetLastError());
return -1;
}
printf("监听套接字为 %d\n", s_listen);
// 2. 绑定端口号和 IP 地址
struct sockaddr_in local = {0}; // 定义本地地址结构体。
local.sin_family = AF_INET; // 设置地址族为 IPv4
local.sin_port = htons(iPort); // 设置端口号,并将其转换为网络字节序。
local.sin_addr.s_addr = htonl(INADDR_ANY); // 设置 IP 地址为任意可用地址和接口
if (bind(s_listen, (struct sockaddr*)&local, sizeof(local)) == SOCKET_ERROR)
{
printf("bind() Failed!!! errcode: %d\n", WSAGetLastError());
return -1;
}
// 3. 监听属性
if (listen(s_listen, 10) == SOCKET_ERROR) // 开始监听连接请求,最大排队数量为 10。
{
printf("start listen failed!!! errcode: %d\n", WSAGetLastError());
return -1;
}
// 4. 等待客户端连接
while (1)
{
SOCKET s_client = accept(s_listen, NULL, NULL); // 接受客户端连接。
if (s_client == INVALID_SOCKET) // 检查连接是否成功。
{
continue;
}
printf("端口号: %llu 成为新连接\n", s_client);
SOCKET* sockfd = (SOCKET*)malloc(sizeof(SOCKET)); // 分配内存存储客户端套接字。
*sockfd = s_client; // 将客户端套接字赋值给新分配的内存。
unsigned threadId; // 定义线程 ID。
_beginthreadex(NULL, 0, thread_func, sockfd, 0, &threadId); // 创建新线程处理客户端连接。
}
// 清理资源
WSACleanup();
return 0;
}
```
### 客户端代码 (`client.c`)
```c
#define DEFAULT_PORT 5050 // 默认端口号
#define BUFFER_SIZE 1024 // 缓冲区大小
#define _WINSOCK_DEPRECATED_NO_WARNINGS // 忽略 Winsock 过时警告
#include <stdio.h>
#include <string.h>
#include <winsock2.h>
#include <ws2tcpip.h>
#pragma comment(lib, "ws2_32.lib") // 告诉编译器链接 Winsock 库
int main()
{
int iPort = DEFAULT_PORT;
WSADATA wsaData;
WSAStartup(MAKEWORD(2, 2), &wsaData);
// 1. 创建一个 IPv4 流式套接字。
SOCKET s_client = socket(AF_INET, SOCK_STREAM, 0);
if (s_client == INVALID_SOCKET)
{
printf("socket() Failed: %d\n", WSAGetLastError());
return -1;
}
// 2. 连接服务器
struct sockaddr_in target; // 定义目标地址结构体。
target.sin_family = AF_INET; // 设置地址族为 IPv4。
target.sin_port = htons(iPort); // 设置端口号,并将其转换为网络字节序。
target.sin_addr.s_addr = inet_addr("127.0.0.1"); // 将主机数转换成无符号长整形的网络字节顺序
if (-1 == connect(s_client, (struct sockaddr*)&target, sizeof(target)))
{
printf("connect server failed!!!\n");
closesocket(s_client);
return -1;
}
while (1)
{
char choice[10];
printf("请选择传输模式 (text/file): ");
scanf("%s", choice);
if (strcmp(choice, "text") == 0)
{
// 发送普通文本数据
send(s_client, "text", strlen("text"), 0);
char sbuffer[BUFFER_SIZE] = {0}; // 定义发送数据的缓冲区。
printf("请输入数据: ");
scanf("%s", sbuffer);
send(s_client, sbuffer, strlen(sbuffer), 0); // 将数据发送到服务器。
char rbuffer[BUFFER_SIZE] = {0}; // 定义接收数据的缓冲区。
int ret = recv(s_client, rbuffer, 1024, 0); // 接收服务器返回的数据。
if (ret <= 0) break; // 如果接收失败或服务器断开连接,则退出循环。
printf("服务器成功接收到数据:%s\n", rbuffer); // 打印接收到的数据。
}
else if (strcmp(choice, "file") == 0)
{
// 发送文件
send(s_client, "file", strlen("file"), 0);
char filename[BUFFER_SIZE] = {0};
printf("请输入要发送的文件路径: ");
scanf("%s", filename);
FILE *fp = fopen(filename, "rb");
if (!fp)
{
printf("无法打开文件.\n");
continue;
}
send(s_client, filename, strlen(filename), 0); // 发送文件名
while (1)
{
char buffer[BUFFER_SIZE] = {0};
size_t bytes_read = fread(buffer, 1, BUFFER_SIZE, fp);
if (bytes_read > 0)
{
send(s_client, buffer, bytes_read, 0);
}
if (bytes_read < BUFFER_SIZE) break; // 文件传输结束
}
fclose(fp);
printf("文件已发送.\n");
}
else
{
printf("未知模式: %s\n", choice);
}
}
// 4. 关闭连接
closesocket(s_client);
WSACleanup();
return 0;
}
```
### 说明
1. **服务器端**:
- 在 `thread_func` 中增加了对传输模式的判断。
- 支持两种模式:`text` 和 `file`。
- 对于 `text` 模式,直接接收和发送普通文本数据。
- 对于 `file` 模式,先接收文件名,然后接收文件内容并保存到本地文件。
2. **客户端**:
- 增加了一个选择传输模式的提示。
- 根据用户输入的模式,发送相应的命令到服务器。
- 对于 `text` 模式,直接发送和接收普通文本数据。
- 对于 `file` 模式,先发送文件名,然后逐块发送文件内容。
这样,客户端就可以选择是发送普通数据还是文件了。
阅读全文
相关推荐
















