c - TCP 客户端连接到两个 TCP 服务器
问题描述
这是其中一个 TCP 服务器的代码(它也是一个 UDP 客户端,但这不重要),我们称之为 FS
#include <unistd.h>
#include <stdio.h>
#include <string.h>
#include <stdlib.h>
#include <sys/types.h>
#include <sys/stat.h>
#include <sys/socket.h>
#include <netinet/in.h>
#include <arpa/inet.h>
#include <netdb.h>
#include <errno.h>
int max(int fd, int fd2){
if(fd > fd2) return fd;
else return fd2;
int main(int argc, char *argv[]){
int ASfd, errcode, listenfd, User_fd;
ssize_t n;
socklen_t addrlen, addrlen2;
struct addrinfo hints, hints2, *res, *res2;
struct sockaddr_in addr;
struct sockaddr_in addr2;
fd_set readfds;
int pid;
char* AS_PORT = argv[3];
char* AS_IP = argv[2];
char* FS_PORT = argv[1];
char buffer[364];
char check[4], num_aluno[6], Fname[64], Fcontent[128];
long Fsize;
//TCP SOCKET
listenfd = socket(AF_INET,SOCK_STREAM,0);
if(listenfd == -1) exit(1);
memset(&hints2,0,sizeof hints2);
hints2.ai_family=AF_INET;
hints2.ai_socktype=SOCK_STREAM;
hints2.ai_flags=AI_PASSIVE;
errcode = getaddrinfo(NULL,FS_PORT,&hints2,&res2);
if(errcode != 0){
perror("getaddrinfo");
exit(1);
}
n=bind(listenfd,res2->ai_addr, res2->ai_addrlen);
if(n==-1) exit(1);
if(listen(listenfd,10) == -1) exit(1);
ASfd = socket(AF_INET,SOCK_DGRAM,0);
if(ASfd==-1) exit(1);
memset(&hints,0,sizeof hints);
hints.ai_family=AF_INET;
hints.ai_socktype=SOCK_DGRAM;
hints.ai_flags=AI_PASSIVE;
errcode = getaddrinfo(AS_IP,AS_PORT,&hints,&res);
if(errcode != 0) exit(1);
addrlen=sizeof(addr);
addrlen2=sizeof(addr2);
while(1){
FD_CLR(ASfd,&readfds);
FD_CLR(listenfd,&readfds);
FD_SET(ASfd,&readfds);
select(max(ASfd,listenfd)+1,&readfds,NULL,NULL,NULL);
if(FD_ISSET(ASfd,&readfds)){
n = recvfrom(ASfd,buffer,128,0,(struct sockaddr*)&addr,&addrlen);
if(n == -1) exit(1);
write(1,buffer,strlen(buffer)+1);
}
else if(FD_ISSET(listenfd,&readfds)){
User_fd = accept(listenfd,(struct sockaddr*)&addr2,&addrlen2);
if(User_fd == -1){
perror("accept");
exit(1);
}
if ((pid = fork())==0) {
close(listenfd);
while(1){
read(User_fd,buffer,364);
write(1,buffer,strlen(buffer)+1);
sscanf(buffer,"%s",check);
if(strcmp(check,"UPL")==0){
sscanf(buffer,"%s %s %s %ld %s",check,num_aluno,Fname,&Fsize,Fcontent);
write(1,Fcontent,strlen(Fcontent)+1);
}
}
freeaddrinfo(res);
close(User_fd);
exit(0);
}
}
}
}
这是我们的第二个 TCP 服务器(它也是一个 UDP 服务器)的代码,我们称之为 AS
int main(){
int fd, errcode, listenfd, newfd;
ssize_t n;
socklen_t addrlen, addrlen2;
struct addrinfo hints, hints2, *res, *res2;
struct sockaddr_in addr;
struct sockaddr_in addr2;
char buffer[128], buffertroll[128];
fd_set readfds;
int status = 0, rid, vc, new_vc = 0, pid, tid;
char Fop;
char check[4], password[9], num_aluno_s[6], PD_IP[64], PD_PORT[6], path[64], Fname[64];
//TCP SOCKET
listenfd = socket(AF_INET,SOCK_STREAM,0);
if(listenfd == -1) exit(1);
memset(&hints2,0,sizeof hints2);
hints2.ai_family=AF_INET;
hints2.ai_socktype=SOCK_STREAM;
hints2.ai_flags=AI_PASSIVE;
errcode = getaddrinfo(NULL,PORT,&hints2,&res2);
if(errcode != 0) exit(1);
n=bind(listenfd,res2->ai_addr, res2->ai_addrlen);
if(n==-1) exit(1);
if(listen(listenfd,10) == -1) exit(1);
//UDP SOCKET (PD)
fd = socket(AF_INET,SOCK_DGRAM,0);
if(fd==-1) exit(1);
memset(&hints,0,sizeof hints);
hints.ai_family=AF_INET;
hints.ai_socktype=SOCK_DGRAM;
hints.ai_flags=AI_PASSIVE;
errcode = getaddrinfo(NULL,PORT,&hints,&res);
if(errcode != 0) exit(1);
n=bind(fd,res->ai_addr, res->ai_addrlen);
if(n==-1) exit(1);
mkdir("Users",0777);
addrlen=sizeof(addr);
addrlen2=sizeof(addr2);
while(1){
FD_CLR(fd,&readfds);
FD_SET(fd,&readfds);
FD_SET(listenfd,&readfds);
select(max(fd,listenfd)+1,&readfds,NULL,NULL,NULL);
/* PD communication */
if(FD_ISSET(fd,&readfds)){
memset(buffer,0,128);
memset(check,0,4);
n=recvfrom(fd,buffer,128,0,(struct sockaddr*)&addr,&addrlen);
if(n==-1) exit(1);
write(1,buffer,strlen(buffer)+1);
sscanf(buffer,"%s %s %s %s %s",check,num_aluno_s,password,PD_IP,PD_PORT);
/* case "register" message */
if(strcmp(check,"REG")==0){
write(1,"PD: new user, UID=",19);
write(1,num_aluno_s,6);
write(1,"\n",1);
sprintf(path,"Users/%s",num_aluno_s);
mkdir(path,0777);
createPassFile(num_aluno_s,password);
createRegFile(num_aluno_s,PD_IP,PD_PORT);
n = sendto(fd,"RRG OK\n",8,0,(struct sockaddr*)&addr,addrlen);
if(n == -1) exit(1);
}
/* case "exit" message */
if(strcmp(check,"UNR")==0){
sscanf(buffer,"%s %s %s",check,num_aluno_s,password);
memset(buffer,0,128);
status = deleteUser(num_aluno_s, password);
if (status) sprintf(buffer, "RUN OK\n");
else sprintf(buffer, "RUN NOK\n");
n = sendto(fd,buffer,strlen(buffer)+1,0,(struct sockaddr*)&addr,addrlen);
if(n == -1) exit(1);
}
}
/* User communication */
else if(FD_ISSET(listenfd,&readfds)){
newfd = accept(listenfd,(struct sockaddr*)&addr2,&addrlen2);
if(newfd == -1){
perror("accept");
exit(1);
}
if ((pid = fork())==0) {
close(listenfd);
while(1) {
memset(buffer,0,128);
memset(check,0,4);
read(newfd,buffer,128);
write(1,buffer,strlen(buffer)+1);
sscanf(buffer,"%s",check);
if(strcmp(check,"LOG")==0){
sscanf(buffer,"%s %s %s",check,num_aluno_s,password);
memset(buffer,0,128);
status = verifyUser(num_aluno_s, password);
if (status == 1){
sprintf(buffer,"User: login ok, UID=%s",num_aluno_s);
write(1,buffer,strlen(buffer)+1);
memset(buffer,0,128);
sprintf(buffer, "RLO OK\n");
createLogFile(num_aluno_s);
}
else if (status == 0) sprintf(buffer, "RLO NOK\n");
else sprintf(buffer, "ERR\n");
write(newfd,buffer,strlen(buffer)+1);
}
else if (strcmp(check,"REQ")==0){
sscanf(buffer,"%s %s %d %c %s",check,num_aluno_s,&rid,&Fop,Fname);
memset(buffer,0,128);
status = verifyLogin(num_aluno_s);
if (status) {
new_vc = getVC();
if (Fop == 'R' || Fop == 'U' || Fop == 'D') {
sprintf(buffer,"VLC %s %04d %c %s\n", num_aluno_s, new_vc, Fop, Fname);
sprintf(buffertroll,"User: upload req, UID=%s file: %s, RID=%d VC=%04d\n",num_aluno_s,Fname,rid,new_vc);
write(1,buffertroll,strlen(buffertroll)+1);
if (sendto(fd,buffer,strlen(buffer)+1,0,(struct sockaddr*)&addr,addrlen) == -1){
write(newfd,"RRQ EPD\n",9);
}
}
else if (Fop == 'L' || Fop == 'X') {
sprintf(buffer,"VLC %s %04d %c\n", num_aluno_s, new_vc, Fop);
if (sendto(fd,buffer,strlen(buffer)+1,0,(struct sockaddr*)&addr,addrlen) == -1)
write(newfd,"RRQ EPD\n",9);
}
else write(newfd,"RRQ EFOP\n",10);
} else write(newfd,"RRQ ELOG\n",10);
}
else if (strcmp(check,"AUT")==0){
sscanf(buffer,"%s %s %d %d", check, num_aluno_s, &rid, &vc);
if (new_vc == vc){
tid = getVC();
memset(buffertroll,0,128);
sprintf(buffertroll,"User: UID=%s %c, %s, TID=%04d\n",num_aluno_s,Fop,Fname,tid);
write(1,buffertroll,strlen(buffertroll)+1);
memset(buffertroll,0,128);
sprintf(buffertroll,"RAU %04d\n",tid);
write(newfd,buffertroll,strlen(buffertroll)+1);
createTIDFile(Fop,Fname,tid,num_aluno_s);
}
}
else if(strcmp(check,"EXT")==0){
memset(buffertroll,0,128);
if(deleteLogFile(num_aluno_s)==0){
write(newfd,"EXT NOK\n",8);
continue;
}
deleteTIDFile(num_aluno_s);
write(newfd,"EXT OK\n",7);
break;
}
}
freeaddrinfo(res);
close(newfd);
exit(0);
}
}
memset(num_aluno_s,0,6);
memset(password,0,9);
}
freeaddrinfo(res);
close(fd);
return 0;
}
这是用于连接到两个 TCP 服务器的代码
//AS Connection
fd = socket(AF_INET,SOCK_STREAM,0);
if(fd==-1) exit(1);
memset(&hints,0,sizeof hints);
hints.ai_family=AF_INET;
hints.ai_socktype=SOCK_STREAM;
errcode = getaddrinfo(AS_IP,AS_PORT,&hints,&res);
if(errcode != 0) exit(1);
n = connect(fd,res->ai_addr,res->ai_addrlen);
if(n==-1) exit(1);
//FS Connection
FSfd = socket(AF_INET,SOCK_STREAM,0);
if(FSfd==-1) exit(1);
memset(&hints2,0,sizeof hints2);
hints2.ai_family=AF_INET;
hints2.ai_socktype=SOCK_STREAM;
errcode = getaddrinfo(FS_IP,FS_PORT,&hints2,&res2);
if(errcode != 0){
perror("lmao");
exit(1);
}
n = connect(FSfd,res2->ai_addr,res2->ai_addrlen);
if(n==-1) exit(1);
现在我们的客户端在 AS 上运行良好,但我们无法与 FS 连接(accept 从不接受任何连接并且它被阻止在那里),我无法弄清楚我做错了什么。
解决方案
FS Code需要是这样的
#include <unistd.h>
#include <stdio.h>
#include <string.h>
#include <stdlib.h>
#include <sys/types.h>
#include <sys/stat.h>
#include <sys/socket.h>
#include <netinet/in.h>
#include <arpa/inet.h>
#include <netdb.h>
#include <errno.h>
int max(int fd, int fd2){
if(fd > fd2) return fd;
else return fd2;
int main(int argc, char *argv[]){
int ASfd, errcode, listenfd, User_fd;
ssize_t n;
socklen_t addrlen, addrlen2;
struct addrinfo hints, hints2, *res, *res2;
struct sockaddr_in addr;
struct sockaddr_in addr2;
fd_set readfds;
int pid;
char* AS_PORT = argv[3];
char* AS_IP = argv[2];
char* FS_PORT = argv[1];
char buffer[364];
char check[4], num_aluno[6], Fname[64], Fcontent[128];
long Fsize;
//TCP SOCKET
listenfd = socket(AF_INET,SOCK_STREAM,0);
if(listenfd == -1) exit(1);
memset(&hints2,0,sizeof hints2);
hints2.ai_family=AF_INET;
hints2.ai_socktype=SOCK_STREAM;
hints2.ai_flags=AI_PASSIVE;
errcode = getaddrinfo(NULL,FS_PORT,&hints2,&res2);
if(errcode != 0){
perror("getaddrinfo");
exit(1);
}
n=bind(listenfd,res2->ai_addr, res2->ai_addrlen);
if(n==-1) exit(1);
if(listen(listenfd,10) == -1) exit(1);
ASfd = socket(AF_INET,SOCK_DGRAM,0);
if(ASfd==-1) exit(1);
memset(&hints,0,sizeof hints);
hints.ai_family=AF_INET;
hints.ai_socktype=SOCK_DGRAM;
hints.ai_flags=AI_PASSIVE;
errcode = getaddrinfo(AS_IP,AS_PORT,&hints,&res);
if(errcode != 0) exit(1);
addrlen=sizeof(addr);
addrlen2=sizeof(addr2);
while(1){
FD_CLR(ASfd,&readfds);
FD_CLR(listenfd,&readfds);
FD_SET(ASfd,&readfds);
FD_SET(listenfd,&readfds);
select(max(ASfd,listenfd)+1,&readfds,NULL,NULL,NULL);
if(FD_ISSET(ASfd,&readfds)){
n = recvfrom(ASfd,buffer,128,0,(struct sockaddr*)&addr,&addrlen);
if(n == -1) exit(1);
write(1,buffer,strlen(buffer)+1);
}
else if(FD_ISSET(listenfd,&readfds)){
User_fd = accept(listenfd,(struct sockaddr*)&addr2,&addrlen2);
if(User_fd == -1){
perror("accept");
exit(1);
}
if ((pid = fork())==0) {
close(listenfd);
while(1){
read(User_fd,buffer,364);
write(1,buffer,strlen(buffer)+1);
sscanf(buffer,"%s",check);
if(strcmp(check,"UPL")==0){
sscanf(buffer,"%s %s %s %ld %s",check,num_aluno,Fname,&Fsize,Fcontent);
write(1,Fcontent,strlen(Fcontent)+1);
}
}
freeaddrinfo(res);
close(User_fd);
exit(0);
}
}
}