简单套接字非阻塞 I/O
我正在尝试在服务器和客户端之间实现非阻塞 I/O。两者连接后,我尝试使用 fork 来处理 IO,但是服务器端在尝试读取“传输端点未连接”时出现错误,并且发生了两次(我猜是因为 fork?) 。
服务器代码
//includes taken out
#define PORT "4950"
#define STDIN 0
struct sockaddr name;
void set_nonblock(int socket) {
int flags;
flags = fcntl(socket,F_GETFL,0);
assert(flags != -1);
fcntl(socket, F_SETFL, flags | O_NONBLOCK);
}
// get sockaddr, IPv4 or IPv6:
void *get_in_addr(struct sockaddr *sa) {
if (sa->sa_family == AF_INET)
return &(((struct sockaddr_in*)sa)->sin_addr);
return &(((struct sockaddr_in6*)sa)->sin6_addr);
}
int main(int agrc, char** argv) {
int status, sock, adrlen, new_sd;
struct addrinfo hints;
struct addrinfo *servinfo; //will point to the results
//store the connecting address and size
struct sockaddr_storage their_addr;
socklen_t their_addr_size;
//socket infoS
memset(&hints, 0, sizeof hints); //make sure the struct is empty
hints.ai_family = AF_INET;
hints.ai_socktype = SOCK_STREAM; //tcp
hints.ai_flags = AI_PASSIVE; //use local-host address
//get server info, put into servinfo
if ((status = getaddrinfo("127.0.0.1", PORT, &hints, &servinfo)) != 0) {
fprintf(stderr, "getaddrinfo error: %s\n", gai_strerror(status));
exit(1);
}
//make socket
sock = socket(servinfo->ai_family, servinfo->ai_socktype, servinfo->ai_protocol);
if (sock < 0) {
printf("\nserver socket failure %m", errno);
exit(1);
}
//allow reuse of port
int yes=1;
if (setsockopt(sock,SOL_SOCKET,SO_REUSEADDR,&yes,sizeof(int)) == -1) {
perror("setsockopt");
exit(1);
}
//unlink and bind
unlink("127.0.0.1");
if(bind (sock, servinfo->ai_addr, servinfo->ai_addrlen) < 0) {
printf("\nBind error %m", errno);
exit(1);
}
freeaddrinfo(servinfo);
//listen
if(listen(sock, 5) < 0) {
printf("\nListen error %m", errno);
exit(1);
}
their_addr_size = sizeof(their_addr);
//accept
new_sd = accept(sock, (struct sockaddr*)&their_addr, &their_addr_size);
if( new_sd < 0) {
printf("\nAccept error %m", errno);
exit(1);
}
cout<<"\nSuccessful Connection!";
//set nonblock
set_nonblock(new_sd);
char* in = new char[255];
char* out = new char[255];
int numSent;
int numRead;
pid_t pid;
fork();
pid = getpid();
if(pid == 0) {
while( !(out[0] == 'q' && out[1] == 'u' && out[2] == 'i' && out[3] == 't') ) {
fgets(out, 255, stdin);
numSent = send(sock, out, strlen(out), 0);
if(numSent < 0) {
printf("\nError sending %m", errno);
exit(1);
} //end error
} //end while
} //end child
else {
numRead = recv(sock, in, 255, 0);
if(numRead < 0) {
printf("\nError reading %m", errno);
exit(1);
} //end error
else {
cout<<in;
for(int i=0;i<255;i++)
in[i] = '\0';
} //end else
} //end parent
cout<<"\n\nExiting normally\n";
return 0;
}
客户端代码
//includes 取出
#define PORT "4950"
struct sockaddr name;
void set_nonblock(int socket) {
int flags;
flags = fcntl(socket,F_GETFL,0);
assert(flags != -1);
fcntl(socket, F_SETFL, flags | O_NONBLOCK);
}
// get sockaddr, IPv4 or IPv6:
void *get_in_addr(struct sockaddr *sa) {
if (sa->sa_family == AF_INET)
return &(((struct sockaddr_in*)sa)->sin_addr);
return &(((struct sockaddr_in6*)sa)->sin6_addr);
}
int main(int agrc, char** argv) {
int status, sock, adrlen;
struct addrinfo hints;
struct addrinfo *servinfo; //will point to the results
memset(&hints, 0, sizeof hints); //make sure the struct is empty
hints.ai_family = AF_INET;
hints.ai_socktype = SOCK_STREAM; //tcp
hints.ai_flags = AI_PASSIVE; //use local-host address
//get server info, put into servinfo
if ((status = getaddrinfo("127.0.0.1", PORT, &hints, &servinfo)) != 0) {
fprintf(stderr, "getaddrinfo error: %s\n", gai_strerror(status));
exit(1);
}
//make socket
sock = socket(servinfo->ai_family, servinfo->ai_socktype, servinfo->ai_protocol);
if (sock < 0) {
printf("\nserver socket failure %m", errno);
exit(1);
}
if(connect(sock, servinfo->ai_addr, servinfo->ai_addrlen) < 0) {
printf("\nclient connection failure %m", errno);
exit(1);
}
cout<<"\nSuccessful connection!";
//set nonblock
set_nonblock(sock);
char* out = new char[255];
char* in = new char[255];
int numRead;
int numSent;
pid_t pid;
fork();
pid = getpid();
if(pid == 0) {
while( !(out[0] == 'q' && out[1] == 'u' && out[2] == 'i' && out[3] == 't') ) {
fgets(out, 255, stdin);
numSent = send(sock, out, strlen(out), 0);
if(numSent < 0) {
printf("\nError sending %m", errno);
exit(1);
} //end error
} //end while
} //end child process
else {
while( !(in[0] == 'q' && in[1] == 'u' && in[2] == 'i' && in[3] == 't') ) {
numRead = recv(sock, in, 255, 0);
cout<<in;
for(int i=0;i<255;i++)
in[i] = '\0';
}
} //end parent process
cout<<"\n\nExiting normally\n";
return 0;
}
我还尝试使用线程来执行 I/O。问题在于,当我运行该程序时,就像线程没有发生一样。该程序只是运行“连接成功”,然后“正常退出”。我将一些 cout 语句放入 while(1) 循环中,它们确实打印了几次,但它们只是由于某种原因停止了。我不确定我的线程或套接字是否有问题。代码(与上面非常相似)在这里 -
服务器
//includes taken out
#define PORT "4950"
#define STDIN 0
pthread_t readthread;
pthread_t sendthread;
char* in = new char[255];
char* out = new char[255];
int numSent;
int numRead;
struct sockaddr name;
int sock, new_sd;
void* readThread(void* threadid) {
while(1) {
numRead = recv(new_sd, in, 255, 0);
if(numRead > 0) {
cout<<"\n"<<in;
for(int i=0;i<strlen(in);i++)
in[i] = '\0';
} //end if
else if(numRead < 0) {
printf("\nError reading %m", errno);
exit(1);
}
} //end while
} //END READTHREAD
void* sendThread(void* threadid) {
while(1) {
cin.getline(out, 255);
numSent = send(new_sd, out, 255, 0);
if(numSent > 0) {
for(int i=0;i<strlen(out);i++)
out[i] = '\0';
} //end if
else if(numSent < 0) {
printf("\nError sending %m", errno);
exit(1);
}
} //end while
} //END SENDTHREAD
void set_nonblock(int socket) {
int flags;
flags = fcntl(socket,F_GETFL,0);
assert(flags != -1);
fcntl(socket, F_SETFL, flags | O_NONBLOCK);
}
// get sockaddr, IPv4 or IPv6:
void *get_in_addr(struct sockaddr *sa) {
if (sa->sa_family == AF_INET)
return &(((struct sockaddr_in*)sa)->sin_addr);
return &(((struct sockaddr_in6*)sa)->sin6_addr);
}
int main(int agrc, char** argv) {
int status, adrlen;
struct addrinfo hints;
struct addrinfo *servinfo; //will point to the results
//store the connecting address and size
struct sockaddr_storage their_addr;
socklen_t their_addr_size;
//socket infoS
memset(&hints, 0, sizeof hints); //make sure the struct is empty
hints.ai_family = AF_INET;
hints.ai_socktype = SOCK_STREAM; //tcp
hints.ai_flags = AI_PASSIVE; //use local-host address
//get server info, put into servinfo
if ((status = getaddrinfo("127.0.0.1", PORT, &hints, &servinfo)) != 0) {
fprintf(stderr, "getaddrinfo error: %s\n", gai_strerror(status));
exit(1);
}
//make socket
sock = socket(servinfo->ai_family, servinfo->ai_socktype, servinfo->ai_protocol);
if (sock < 0) {
printf("\nserver socket failure %m", errno);
exit(1);
}
//allow reuse of port
int yes=1;
if (setsockopt(sock,SOL_SOCKET,SO_REUSEADDR,&yes,sizeof(int)) == -1) {
perror("setsockopt");
exit(1);
}
//unlink and bind
unlink("127.0.0.1");
if(bind (sock, servinfo->ai_addr, servinfo->ai_addrlen) < 0) {
printf("\nBind error %m", errno);
exit(1);
}
freeaddrinfo(servinfo);
//listen
if(listen(sock, 5) < 0) {
printf("\nListen error %m", errno);
exit(1);
}
their_addr_size = sizeof(their_addr);
//accept
new_sd = accept(sock, (struct sockaddr*)&their_addr, &their_addr_size);
if( new_sd < 0) {
printf("\nAccept error %m", errno);
exit(1);
}
cout<<"\nSuccessful Connection!";
//set nonblock
set_nonblock(new_sd);
pthread_attr_t attr;
pthread_attr_init(&attr);
pthread_attr_setdetachstate(&attr, PTHREAD_CREATE_JOINABLE);
pthread_create(&readthread, &attr, readThread, (void*)0);
pthread_create(&sendthread, &attr, sendThread, (void*)1);
cout<<"\n\nExiting normally\n";
return 0;
}
客户端
#define PORT "4950"
pthread_t readthread;
pthread_t sendthread;
char* in = new char[255];
char* out = new char[255];
int numSent;
int numRead;
struct sockaddr name;
int sock;
void* readThread(void* threadid) {
while(1) {
numRead = recv(sock, in, 255, 0);
if(numRead > 0) {
cout<<"\n"<<in;
for(int i=0;i<strlen(in);i++)
in[i] = '\0';
} //end if
else if(numRead < 0) {
printf("\nError reading %m", errno);
exit(1);
}
} //end while
} //END READTHREAD
void* sendThread(void* threadid) {
while(1) {
cin.getline(out, 255);
numSent = send(sock, out, 255, 0);
if(numSent > 0) {
for(int i=0;i<strlen(out);i++)
out[i] = '\0';
} //end if
else if(numSent < 0) {
printf("\nError sending %m", errno);
exit(1);
}
} //end while
} //END SENDTHREAD
void set_nonblock(int socket) {
int flags;
flags = fcntl(socket,F_GETFL,0);
assert(flags != -1);
fcntl(socket, F_SETFL, flags | O_NONBLOCK);
}
// get sockaddr, IPv4 or IPv6:
void *get_in_addr(struct sockaddr *sa) {
if (sa->sa_family == AF_INET)
return &(((struct sockaddr_in*)sa)->sin_addr);
return &(((struct sockaddr_in6*)sa)->sin6_addr);
}
int main(int agrc, char** argv) {
int status, adrlen;
struct addrinfo hints;
struct addrinfo *servinfo; //will point to the results
memset(&hints, 0, sizeof hints); //make sure the struct is empty
hints.ai_family = AF_INET;
hints.ai_socktype = SOCK_STREAM; //tcp
hints.ai_flags = AI_PASSIVE; //use local-host address
//get server info, put into servinfo
if ((status = getaddrinfo("127.0.0.1", PORT, &hints, &servinfo)) != 0) {
fprintf(stderr, "getaddrinfo error: %s\n", gai_strerror(status));
exit(1);
}
//make socket
sock = socket(servinfo->ai_family, servinfo->ai_socktype, servinfo->ai_protocol);
if (sock < 0) {
printf("\nserver socket failure %m", errno);
exit(1);
}
if(connect(sock, servinfo->ai_addr, servinfo->ai_addrlen) < 0) {
printf("\nclient connection failure %m", errno);
exit(1);
}
cout<<"\nSuccessful connection!";
//set nonblock
set_nonblock(sock);
pthread_attr_t attr;
pthread_attr_init(&attr);
pthread_attr_setdetachstate(&attr, PTHREAD_CREATE_JOINABLE);
pthread_create(&readthread, &attr, readThread, (void*)0);
pthread_create(&sendthread, &attr, sendThread, (void*)1);
cout<<"\n\nExiting normally\n";
return 0;
}
我对长篇文章表示歉意,但我已经在这几天了,不知道如何继续。我尝试使用 select(),但这对于 1 个客户端和一个服务器 I/O 来说似乎有点多了。如果有人能指出上面可能出现的问题或任何其他提示(或者我对 select 的理解完全错误:)),我将不胜感激。
I am trying have non-blocking I/O between a server and client. After the two are connected, I am trying to use fork to handle the IO, but the server side gets an error when trying to read of "Transport endpoint is not connected" and it happens twice (because of fork I'm guessing?).
Server code
//includes taken out
#define PORT "4950"
#define STDIN 0
struct sockaddr name;
void set_nonblock(int socket) {
int flags;
flags = fcntl(socket,F_GETFL,0);
assert(flags != -1);
fcntl(socket, F_SETFL, flags | O_NONBLOCK);
}
// get sockaddr, IPv4 or IPv6:
void *get_in_addr(struct sockaddr *sa) {
if (sa->sa_family == AF_INET)
return &(((struct sockaddr_in*)sa)->sin_addr);
return &(((struct sockaddr_in6*)sa)->sin6_addr);
}
int main(int agrc, char** argv) {
int status, sock, adrlen, new_sd;
struct addrinfo hints;
struct addrinfo *servinfo; //will point to the results
//store the connecting address and size
struct sockaddr_storage their_addr;
socklen_t their_addr_size;
//socket infoS
memset(&hints, 0, sizeof hints); //make sure the struct is empty
hints.ai_family = AF_INET;
hints.ai_socktype = SOCK_STREAM; //tcp
hints.ai_flags = AI_PASSIVE; //use local-host address
//get server info, put into servinfo
if ((status = getaddrinfo("127.0.0.1", PORT, &hints, &servinfo)) != 0) {
fprintf(stderr, "getaddrinfo error: %s\n", gai_strerror(status));
exit(1);
}
//make socket
sock = socket(servinfo->ai_family, servinfo->ai_socktype, servinfo->ai_protocol);
if (sock < 0) {
printf("\nserver socket failure %m", errno);
exit(1);
}
//allow reuse of port
int yes=1;
if (setsockopt(sock,SOL_SOCKET,SO_REUSEADDR,&yes,sizeof(int)) == -1) {
perror("setsockopt");
exit(1);
}
//unlink and bind
unlink("127.0.0.1");
if(bind (sock, servinfo->ai_addr, servinfo->ai_addrlen) < 0) {
printf("\nBind error %m", errno);
exit(1);
}
freeaddrinfo(servinfo);
//listen
if(listen(sock, 5) < 0) {
printf("\nListen error %m", errno);
exit(1);
}
their_addr_size = sizeof(their_addr);
//accept
new_sd = accept(sock, (struct sockaddr*)&their_addr, &their_addr_size);
if( new_sd < 0) {
printf("\nAccept error %m", errno);
exit(1);
}
cout<<"\nSuccessful Connection!";
//set nonblock
set_nonblock(new_sd);
char* in = new char[255];
char* out = new char[255];
int numSent;
int numRead;
pid_t pid;
fork();
pid = getpid();
if(pid == 0) {
while( !(out[0] == 'q' && out[1] == 'u' && out[2] == 'i' && out[3] == 't') ) {
fgets(out, 255, stdin);
numSent = send(sock, out, strlen(out), 0);
if(numSent < 0) {
printf("\nError sending %m", errno);
exit(1);
} //end error
} //end while
} //end child
else {
numRead = recv(sock, in, 255, 0);
if(numRead < 0) {
printf("\nError reading %m", errno);
exit(1);
} //end error
else {
cout<<in;
for(int i=0;i<255;i++)
in[i] = '\0';
} //end else
} //end parent
cout<<"\n\nExiting normally\n";
return 0;
}
Client code
//includes taken out
#define PORT "4950"
struct sockaddr name;
void set_nonblock(int socket) {
int flags;
flags = fcntl(socket,F_GETFL,0);
assert(flags != -1);
fcntl(socket, F_SETFL, flags | O_NONBLOCK);
}
// get sockaddr, IPv4 or IPv6:
void *get_in_addr(struct sockaddr *sa) {
if (sa->sa_family == AF_INET)
return &(((struct sockaddr_in*)sa)->sin_addr);
return &(((struct sockaddr_in6*)sa)->sin6_addr);
}
int main(int agrc, char** argv) {
int status, sock, adrlen;
struct addrinfo hints;
struct addrinfo *servinfo; //will point to the results
memset(&hints, 0, sizeof hints); //make sure the struct is empty
hints.ai_family = AF_INET;
hints.ai_socktype = SOCK_STREAM; //tcp
hints.ai_flags = AI_PASSIVE; //use local-host address
//get server info, put into servinfo
if ((status = getaddrinfo("127.0.0.1", PORT, &hints, &servinfo)) != 0) {
fprintf(stderr, "getaddrinfo error: %s\n", gai_strerror(status));
exit(1);
}
//make socket
sock = socket(servinfo->ai_family, servinfo->ai_socktype, servinfo->ai_protocol);
if (sock < 0) {
printf("\nserver socket failure %m", errno);
exit(1);
}
if(connect(sock, servinfo->ai_addr, servinfo->ai_addrlen) < 0) {
printf("\nclient connection failure %m", errno);
exit(1);
}
cout<<"\nSuccessful connection!";
//set nonblock
set_nonblock(sock);
char* out = new char[255];
char* in = new char[255];
int numRead;
int numSent;
pid_t pid;
fork();
pid = getpid();
if(pid == 0) {
while( !(out[0] == 'q' && out[1] == 'u' && out[2] == 'i' && out[3] == 't') ) {
fgets(out, 255, stdin);
numSent = send(sock, out, strlen(out), 0);
if(numSent < 0) {
printf("\nError sending %m", errno);
exit(1);
} //end error
} //end while
} //end child process
else {
while( !(in[0] == 'q' && in[1] == 'u' && in[2] == 'i' && in[3] == 't') ) {
numRead = recv(sock, in, 255, 0);
cout<<in;
for(int i=0;i<255;i++)
in[i] = '\0';
}
} //end parent process
cout<<"\n\nExiting normally\n";
return 0;
}
I also tried using threads to do the I/O. The problem there is that when I run the program, its like the threads don't occur. The program just runs with a "Successful Connection" and then "exiting normally." I put some cout statements into the while(1) loops and they did print out a few times, but they just stop for some reason. I'm not sure if its a problem with my threads or my sockets. The code (very similar to above) for that is here -
Server
//includes taken out
#define PORT "4950"
#define STDIN 0
pthread_t readthread;
pthread_t sendthread;
char* in = new char[255];
char* out = new char[255];
int numSent;
int numRead;
struct sockaddr name;
int sock, new_sd;
void* readThread(void* threadid) {
while(1) {
numRead = recv(new_sd, in, 255, 0);
if(numRead > 0) {
cout<<"\n"<<in;
for(int i=0;i<strlen(in);i++)
in[i] = '\0';
} //end if
else if(numRead < 0) {
printf("\nError reading %m", errno);
exit(1);
}
} //end while
} //END READTHREAD
void* sendThread(void* threadid) {
while(1) {
cin.getline(out, 255);
numSent = send(new_sd, out, 255, 0);
if(numSent > 0) {
for(int i=0;i<strlen(out);i++)
out[i] = '\0';
} //end if
else if(numSent < 0) {
printf("\nError sending %m", errno);
exit(1);
}
} //end while
} //END SENDTHREAD
void set_nonblock(int socket) {
int flags;
flags = fcntl(socket,F_GETFL,0);
assert(flags != -1);
fcntl(socket, F_SETFL, flags | O_NONBLOCK);
}
// get sockaddr, IPv4 or IPv6:
void *get_in_addr(struct sockaddr *sa) {
if (sa->sa_family == AF_INET)
return &(((struct sockaddr_in*)sa)->sin_addr);
return &(((struct sockaddr_in6*)sa)->sin6_addr);
}
int main(int agrc, char** argv) {
int status, adrlen;
struct addrinfo hints;
struct addrinfo *servinfo; //will point to the results
//store the connecting address and size
struct sockaddr_storage their_addr;
socklen_t their_addr_size;
//socket infoS
memset(&hints, 0, sizeof hints); //make sure the struct is empty
hints.ai_family = AF_INET;
hints.ai_socktype = SOCK_STREAM; //tcp
hints.ai_flags = AI_PASSIVE; //use local-host address
//get server info, put into servinfo
if ((status = getaddrinfo("127.0.0.1", PORT, &hints, &servinfo)) != 0) {
fprintf(stderr, "getaddrinfo error: %s\n", gai_strerror(status));
exit(1);
}
//make socket
sock = socket(servinfo->ai_family, servinfo->ai_socktype, servinfo->ai_protocol);
if (sock < 0) {
printf("\nserver socket failure %m", errno);
exit(1);
}
//allow reuse of port
int yes=1;
if (setsockopt(sock,SOL_SOCKET,SO_REUSEADDR,&yes,sizeof(int)) == -1) {
perror("setsockopt");
exit(1);
}
//unlink and bind
unlink("127.0.0.1");
if(bind (sock, servinfo->ai_addr, servinfo->ai_addrlen) < 0) {
printf("\nBind error %m", errno);
exit(1);
}
freeaddrinfo(servinfo);
//listen
if(listen(sock, 5) < 0) {
printf("\nListen error %m", errno);
exit(1);
}
their_addr_size = sizeof(their_addr);
//accept
new_sd = accept(sock, (struct sockaddr*)&their_addr, &their_addr_size);
if( new_sd < 0) {
printf("\nAccept error %m", errno);
exit(1);
}
cout<<"\nSuccessful Connection!";
//set nonblock
set_nonblock(new_sd);
pthread_attr_t attr;
pthread_attr_init(&attr);
pthread_attr_setdetachstate(&attr, PTHREAD_CREATE_JOINABLE);
pthread_create(&readthread, &attr, readThread, (void*)0);
pthread_create(&sendthread, &attr, sendThread, (void*)1);
cout<<"\n\nExiting normally\n";
return 0;
}
Client
#define PORT "4950"
pthread_t readthread;
pthread_t sendthread;
char* in = new char[255];
char* out = new char[255];
int numSent;
int numRead;
struct sockaddr name;
int sock;
void* readThread(void* threadid) {
while(1) {
numRead = recv(sock, in, 255, 0);
if(numRead > 0) {
cout<<"\n"<<in;
for(int i=0;i<strlen(in);i++)
in[i] = '\0';
} //end if
else if(numRead < 0) {
printf("\nError reading %m", errno);
exit(1);
}
} //end while
} //END READTHREAD
void* sendThread(void* threadid) {
while(1) {
cin.getline(out, 255);
numSent = send(sock, out, 255, 0);
if(numSent > 0) {
for(int i=0;i<strlen(out);i++)
out[i] = '\0';
} //end if
else if(numSent < 0) {
printf("\nError sending %m", errno);
exit(1);
}
} //end while
} //END SENDTHREAD
void set_nonblock(int socket) {
int flags;
flags = fcntl(socket,F_GETFL,0);
assert(flags != -1);
fcntl(socket, F_SETFL, flags | O_NONBLOCK);
}
// get sockaddr, IPv4 or IPv6:
void *get_in_addr(struct sockaddr *sa) {
if (sa->sa_family == AF_INET)
return &(((struct sockaddr_in*)sa)->sin_addr);
return &(((struct sockaddr_in6*)sa)->sin6_addr);
}
int main(int agrc, char** argv) {
int status, adrlen;
struct addrinfo hints;
struct addrinfo *servinfo; //will point to the results
memset(&hints, 0, sizeof hints); //make sure the struct is empty
hints.ai_family = AF_INET;
hints.ai_socktype = SOCK_STREAM; //tcp
hints.ai_flags = AI_PASSIVE; //use local-host address
//get server info, put into servinfo
if ((status = getaddrinfo("127.0.0.1", PORT, &hints, &servinfo)) != 0) {
fprintf(stderr, "getaddrinfo error: %s\n", gai_strerror(status));
exit(1);
}
//make socket
sock = socket(servinfo->ai_family, servinfo->ai_socktype, servinfo->ai_protocol);
if (sock < 0) {
printf("\nserver socket failure %m", errno);
exit(1);
}
if(connect(sock, servinfo->ai_addr, servinfo->ai_addrlen) < 0) {
printf("\nclient connection failure %m", errno);
exit(1);
}
cout<<"\nSuccessful connection!";
//set nonblock
set_nonblock(sock);
pthread_attr_t attr;
pthread_attr_init(&attr);
pthread_attr_setdetachstate(&attr, PTHREAD_CREATE_JOINABLE);
pthread_create(&readthread, &attr, readThread, (void*)0);
pthread_create(&sendthread, &attr, sendThread, (void*)1);
cout<<"\n\nExiting normally\n";
return 0;
}
I apologize for the long post, but I have been at this for a few days now and am not sure how to proceed. I tried using select(), but that seems like a little much for just 1 client and a server I/O. If anyone can point out what may be going wrong above or any other tips (or I'm just plain wrong about select :)) I would greatly appreciate it.
如果你对这篇内容有疑问,欢迎到本站社区发帖提问 参与讨论,获取更多帮助,或者扫码二维码加入 Web 技术交流群。
绑定邮箱获取回复消息
由于您还没有绑定你的真实邮箱,如果其他用户或者作者回复了您的评论,将不能在第一时间通知您!
发布评论
评论(3)
我认为你的问题在这里:
和这里:
你试图在监听套接字上发送和接收。您需要使用
new_sd
这是接受的套接字。请参阅 accept(2) 的手册页。I think your problem is here:
and here:
where you are attempting to
send
andrecv
on your listening socket. You need to usenew_sd
which is the accepted socket. See the man page for accept(2).我已经有一段时间没有做过任何 POSIX 编程了,但是下面的代码看起来有点奇怪:
IIRC,你应该检查子进程的 fork: 0 的返回值,父进程中子进程的 pid。
还没有看过你的其余代码:)
It's been a while since I've done any POSIX programming, but the following code seems a bit odd:
IIRC, you're supposed to check the return value of fork: 0 for the child process, pid of child in the parent process.
Haven't looked at the rest of your code :)
我查看了前两个代码服务器和客户端。不幸的是,您错误地设计了程序。服务器应该执行以下操作(在多进程的情况下):
这是一个伪代码
更新:由于您正在寻找非阻塞场景,我建议您使用 select() 或 poll() 系统调用。
我觉得你想创建两个进程,一个进程用于发送,另一个进程用于接收。如果是这样,那么您不需要将 new_sd 设置为非阻塞模式,因为这两个进程同时运行。如果您打算这样做,那么子进程将创建另一个进程,以便第一个子进程执行发送,第二个子进程执行接收。如下:
I looked at the first two codes server and client. Unfortunately, you designed your program mistakenly. The server is supposed to do the following (in case of multi-processes):
sock
is ONLY responsible to listen for new connection and it is not responsible to send/recv as you did.Here is a pseudo-code
UPDATE: since you are looking for non-blocking scenario, i would recommend you to use select() or poll() system calls.
I feel that you want to create two processes such that one process is for sending and another for receiving. If so, then you don't need to set new_sd to non-blocking mode since these two processes are running at the same time. If you are planning to do that, then the child process will create another process such that the first child do sending and the second child do receiving. As follows: