可能遇到的问题
- 资源竞争:多个进程同时访问和操作网络套接字,可能导致数据混乱、套接字状态不一致等问题。例如,一个进程正在发送数据时,另一个进程同时尝试读取或发送,可能造成数据损坏。
- 数据不一致:不同进程对套接字的读写操作可能相互干扰,导致数据的不完整性或错误解读。
解决思路
- 使用互斥锁(Mutex):互斥锁用于保证在同一时间只有一个进程能够访问网络套接字。当一个进程获取到互斥锁时,其他进程必须等待,直到该进程释放互斥锁。
- 使用信号量(Semaphore):信号量可以控制同时访问网络套接字的进程数量。可以设置信号量的初始值为1,这样就类似于互斥锁的效果;也可以设置大于1的值,允许一定数量的进程同时访问。
示例代码(使用互斥锁)
#include <iostream>
#include <mutex>
#include <unistd.h>
#include <sys/socket.h>
#include <arpa/inet.h>
#include <cstring>
std::mutex socketMutex;
void processTask(int socketFd) {
socketMutex.lock();
// 操作网络套接字
const char* message = "Hello, Server!";
send(socketFd, message, strlen(message), 0);
char buffer[1024];
int bytesRead = recv(socketFd, buffer, sizeof(buffer), 0);
buffer[bytesRead] = '\0';
std::cout << "Received from server: " << buffer << std::endl;
socketMutex.unlock();
}
int main() {
int socketFd = socket(AF_INET, SOCK_STREAM, 0);
if (socketFd == -1) {
perror("Socket creation failed");
return 1;
}
sockaddr_in serverAddr;
serverAddr.sin_family = AF_INET;
serverAddr.sin_port = htons(8080);
serverAddr.sin_addr.s_addr = inet_addr("127.0.0.1");
if (connect(socketFd, (sockaddr*)&serverAddr, sizeof(serverAddr)) == -1) {
perror("Connect failed");
close(socketFd);
return 1;
}
pid_t pid = fork();
if (pid == -1) {
perror("Fork failed");
close(socketFd);
return 1;
} else if (pid == 0) {
// 子进程
processTask(socketFd);
close(socketFd);
_exit(0);
} else {
// 父进程
processTask(socketFd);
wait(nullptr);
close(socketFd);
}
return 0;
}
示例代码(使用信号量)
#include <iostream>
#include <semaphore.h>
#include <unistd.h>
#include <sys/socket.h>
#include <arpa/inet.h>
#include <cstring>
sem_t socketSemaphore;
void processTask(int socketFd) {
sem_wait(&socketSemaphore);
// 操作网络套接字
const char* message = "Hello, Server!";
send(socketFd, message, strlen(message), 0);
char buffer[1024];
int bytesRead = recv(socketFd, buffer, sizeof(buffer), 0);
buffer[bytesRead] = '\0';
std::cout << "Received from server: " << buffer << std::endl;
sem_post(&socketSemaphore);
}
int main() {
sem_init(&socketSemaphore, 0, 1);
int socketFd = socket(AF_INET, SOCK_STREAM, 0);
if (socketFd == -1) {
perror("Socket creation failed");
sem_destroy(&socketSemaphore);
return 1;
}
sockaddr_in serverAddr;
serverAddr.sin_family = AF_INET;
serverAddr.sin_port = htons(8080);
serverAddr.sin_addr.s_addr = inet_addr("127.0.0.1");
if (connect(socketFd, (sockaddr*)&serverAddr, sizeof(serverAddr)) == -1) {
perror("Connect failed");
close(socketFd);
sem_destroy(&socketSemaphore);
return 1;
}
pid_t pid = fork();
if (pid == -1) {
perror("Fork failed");
close(socketFd);
sem_destroy(&socketSemaphore);
return 1;
} else if (pid == 0) {
// 子进程
processTask(socketFd);
close(socketFd);
_exit(0);
} else {
// 父进程
processTask(socketFd);
wait(nullptr);
close(socketFd);
}
sem_destroy(&socketSemaphore);
return 0;
}