我有两个进程,在第一个进程(服务器)为五个客户端提供服务后,它将作业交给第二个进程。为此,我使用套接字。在进程A为特定数量的请求提供服务之后,我希望进程B在同一端口上开始为它们提供服务。 为此,我在进程A中关闭sfd并在进程B中打开它。但是,在绑定时,我遇到绑定错误:地址已经在使用错误,即使在使用SO_REUSEADDR之后。此外,我只在关闭进程A中的sfd以确保绑定成功后才调用进程B. 任何帮助是极大的赞赏。这是代码。处理代码:
#include<stdio.h>
#include<sys/types.h>
#include<sys/socket.h>
#include<stdlib.h>
#include<unistd.h>
#include<string.h>
#include<arpa/inet.h>
#include<sys/time.h>
#include<iostream>
#include<netinet/in.h>
#include<sys/select.h>
#include<sys/shm.h>
#include<signal.h>
using namespace std;
struct shm{
int aid;
int sid;
int bid;
int cid;
int pno;
//int ports[4];
}*val;
int sfds[4];
int count=4;
void func1(int a){
fd_set rfds;
while(1){
FD_ZERO(&rfds);
struct timeval timer;timer.tv_sec=0;timer.tv_usec=10;
for(int i=0;i<count;i++){
FD_SET(sfds[i], &rfds);
}
if(select(sfds[count-1]+1, &rfds, NULL, NULL, &timer)){
for(int i=0;i<count;i++){
if(FD_ISSET(sfds[i], &rfds)){
val->pno = i;
close(sfds[i]);
// Remove the corresponding sfd
for(int j=val->pno;j<count-1;j++){
sfds[j] = sfds[j+1];
}
count--;
kill(val->aid, SIGUSR2);
if(count>0)signal(SIGUSR1, &func1);
else exit(1);
return;
}
}
}
}
}
void func2(int b){
struct sockaddr_in cliaddr;socklen_t clilen;
int lc=0;
for(int i=0;i<3;i++){
int nsfd = accept(sfds[val->pno], (struct sockaddr*)&cliaddr, &clilen);
if(nsfd<0){perror("Error");exit(1);}
cout<<"Connection accepted";
send(nsfd, "OkaA", 5, 0);
close(nsfd);
}
if(close(sfds[val->pno])<0){perror("Error closing");exit(1);}
cout<<"Closed"<<endl;
// Remove the corresponding sfd
for(int i=val->pno;i<count-1;i++){
sfds[i] = sfds[i+1];
}
count--;
kill(val->bid, SIGUSR1);
if(count>0)signal(SIGUSR2, &func2);
else exit(1);
return;
}
int main(){
int shmid = shmget(12345, sizeof(struct shm), IPC_CREAT | 0666);
if(shmid<0){perror("Error");}
val = (struct shm*)shmat(shmid, NULL, 0);
//cout<<"yo2";
signal(SIGUSR1, &func1);
signal(SIGUSR2, &func2);
for(int i=0;i<4;i++){
//val->ports[i] = 7590+i;
sfds[i] = socket(AF_INET, SOCK_STREAM, 0);
const int optVal = 1;
const socklen_t optLen = sizeof(optVal);
int rtn = setsockopt(sfds[i], SOL_SOCKET, SO_REUSEADDR, (void*) &optVal, optLen);
if(rtn<0){perror("Error");exit(1);}
struct sockaddr_in servaddr;
servaddr.sin_family = AF_INET;
servaddr.sin_port = htons(7590+i);
servaddr.sin_addr.s_addr = INADDR_ANY;
if(bind(sfds[i], (struct sockaddr*)&servaddr, sizeof(servaddr))<0){perror("Error");exit(1);}
if(listen(sfds[i],4)<0){perror("Error");exit(1);}
}
int c = fork();
if(c>0){
val->aid = c;
val->sid = getpid();
kill(getpid(), SIGUSR1);
while(1);
}else if(c==0){
while(1);
}else{
perror("Error");exit(1);
}
}
流程B代码:
using namespace std;
struct shm{
int aid;
int sid;
int bid;
int cid;
int pno;
}*val;
int sfds[4];
int count=4;
void func1(int a){
int sfd = socket(AF_INET, SOCK_STREAM, 0);
struct sockaddr_in servaddr;
servaddr.sin_family = AF_INET;
servaddr.sin_port = htons(7590+val->pno);
servaddr.sin_addr.s_addr = INADDR_ANY;
sleep(50);
if(bind(sfd, (struct sockaddr*)&servaddr, sizeof(servaddr))<0){perror("Error");exit(1);}
if(listen(sfd, 4)<0){
perror("Error");exit(1);
}
for(int i=0;i<3;i++){
struct sockaddr_in cliaddr;socklen_t clilen;
int nsfd = accept(sfd, (struct sockaddr*)&cliaddr, &clilen);
send(nsfd, "OkaB", 5, 0);
}
close(sfd);
signal(SIGUSR1, &func1);
kill(val->cid, SIGUSR1);
}
int main(){
signal(SIGUSR1, &func1);
int shmid = shmget(12345, sizeof(struct shm), IPC_CREAT | 0666);
if(shmid<0){perror("Error");}
val = (struct shm*)shmat(shmid, NULL, 0);
val->bid = getpid();
while(1);
}