소켓에 쓰는 동안 내 TCP/IP 클라이언트가 멈 춥니 다. 이는 서버가 close()
(또는 shutdown()
) 호출로 허용 된 연결을 제대로 닫은 경우에도 발생합니다. 난 항상이 사건에 대한 ECONNRESET 오류와 함께 반환되어야한다고 생각했습니다.닫힌 TCP/IP 연결에 쓰기가 응답하지 않는다
동기 출력에서 전화 끊기를 어떻게 방지합니까? 또는 오히려 무엇이 잘못되어 오류가 write()
에 의해보고되지 않습니까?
write()
대신 send()
을 사용해야합니까? 아니면 교환 가능합니까?
두 개의 스레드가있는 별도의 응용 프로그램에서 네트워킹을 테스트하고 있습니다. 주 스레드는 서버 스레드를 시작하고 연결을 허용하고 즉시 닫습니다. 그런 다음 주 스레드는 수신 대기 포트에 연결하여 클라이언트 동작을 모방합니다.
메인 쓰레드 코드 :
sockaddr_in serv_addr;
bzero((char *) &serv_addr, sizeof(serv_addr));
serv_addr.sin_family = AF_INET;
serv_addr.sin_addr.s_addr = INADDR_ANY;
serv_addr.sin_port = htons(port);
int s = socket(AF_INET, SOCK_STREAM, 0);
if (bind(s, (sockaddr*)(&serv_addr), sizeof(serv_addr)) < 0) {
close(s);
throw runtime_error(strerror(errno));
}
listen(s,1);
start_thread(s); // posix thread accepting a connection on s is started here
//Code below imitates TCP/IP client
struct hostent *hp;
struct sockaddr_in addr;
if((hp = gethostbyname(host.c_str())) == NULL){
throw HErrno();
}
bcopy(hp->h_addr, &addr.sin_addr, hp->h_length);
addr.sin_port = htons(port);
addr.sin_family = AF_INET;
int _socket = ::socket(PF_INET, SOCK_STREAM, IPPROTO_TCP);
if (_socket < 0) {
throw Errno();
}
assert(ENOTCONN==107);
assert(_socket>=0);
if(::connect(_socket, (const struct sockaddr *)&addr, sizeof(struct sockaddr_in)) == -1){
throw Errno();
}
while(true) {
const char a[] = "pattern";
if (write(_socket, a, 7)<0) // Writes 30000 times, then hangs
break;
}
서버 스레드 코드 :
int connection = accept(s);
close(connection);
편집 : 내 프로그래밍 오류로 감소 문제. 그것은 제대로 스레드를 받아들이 기 시작하지 못한 것 같습니다.
클라이언트가 연결을 시도 할 때 서버가 이미 수신을 시작했는지 어떻게 확인합니까? – fayyazkl
@fayyazkl, 스레드 시작을 수락하기 전에 수신 대기가 있습니다. 수락 호출이 성공하고 읽을 수있는 fd를 반환합니다. – Basilevs
@fayyazkl 그게 문제라면 그는 write()를 멈추지 않고 연결 만 할 것이다. – EJP