gpt4 book ai didi

c++ - 为什么我的客户端会杀死我的服务器?

转载 作者:太空狗 更新时间:2023-10-29 23:37:43 26 4
gpt4 key购买 nike

怎么线程退出了,父进程也退出了?当我运行服务器时,一切都很好。它坐在 socket 上收听。当客户端连接服务器线程为其提供服务时。当他们来回交谈时,客户端退出,服务器也退出。我正在使用 pthread.h 进行线程处理。它们在这里!

首先是客户端:

#include <netinet/in.h>
#include <netdb.h>
#include <signal.h>
#include <sys/types.h>
#include <sys/socket.h>
#include <sys/un.h>
#include <stdlib.h>
#include <stdio.h>
#include <iostream>
#include <string>
#include <unistd.h>
#include <fcntl.h>
#include <pthread.h>

#define CLIENT_CONNECTED 0
#define CLIENT_NOT_CONNECTED 1
#define PORT 9999
#define MAX_CLIENTS 100

using namespace std;

struct client {
int socket;
int state;
pthread_t tid;
};

int
connectToServer (char *address )
{
struct hostent *hostinfo;
struct sockaddr_in name;
int s;
int rc = 0;

if ( ( s = socket( AF_INET, SOCK_STREAM, 0 ) ) < 0 )
{
cerr<<"Client could not declare socket"<<"\n";
exit( 1 );
}

name.sin_family = AF_INET;
name.sin_port = htons ( ( unsigned short int ) PORT );
name.sin_addr.s_addr = htonl( INADDR_ANY );
hostinfo = gethostbyname ( address );

if ( hostinfo == NULL )
{
cerr<<"Host unknown"<<"\n";
exit( 1 );
}

name.sin_addr = *( struct in_addr * ) hostinfo->h_addr;

if ( connect( s, ( const sockaddr * ) &name, sizeof( name ) ) < 0 )
{
cerr<<"Could not connect to host"<<"\n";
exit( 1 );
}
else
{
/* if( fcntl( s, F_SETFL, O_NONBLOCK ) == -1 )
{
perror( "fcntl" );
exit( 1 );
} */

char readbuf[1024];
char message[ ] = "START";
rc = send( s, message, strlen(message), 0 );
cout<<"RC on send() was "<<rc<<"\n";
if ( rc > 0 )
{
cout<<"using recv...\n";

while( ( rc = recv( s, readbuf, 1, 0 ) ) > 0 )
{
readbuf[ rc ] = '\0';
cout<<"Server responds with: "<<readbuf<<"\n";
}

return true;
}
else
{
return false;
}
}
}

void
killsignal( int param )
{
fprintf( stderr, "Disconnecting." );
exit( 1 );
}

int
main ( )
{
signal( SIGKILL, killsignal );
signal( SIGINT, killsignal );

char address[] = "localhost";
connectToServer( address );
}

和服务器:

#include <netinet/in.h>
#include <netdb.h>
#include <signal.h>
#include <sys/types.h>
#include <sys/socket.h>
#include <sys/un.h>
#include <stdlib.h>
#include <stdio.h>
#include <iostream>
#include <string>
#include <unistd.h>
#include <fcntl.h>
#include <pthread.h>

#define CLIENT_CONNECTED 0
#define CLIENT_NOT_CONNECTED 1
#define PORT 9999
#define MAX_CLIENTS 100

using namespace std;

struct client {
int socket;
int state;
pthread_t tid;
};

int
sendClient( char *message, int *socket )
{
int rc = 0;
cout<<message<<"\n";
rc = send( *socket, message, strlen(message), 0 );
cout<<"send RC is: "<<rc<<"\n";
}

void
strtochrstr( char **to, string from )
{

int len = from.size( );

*to = ( char * )malloc( ( len + 1 ) * sizeof( char ) );

if ( to == NULL ){
cout<<"out of memory!\n";
exit( 1 );
}

*to[ 0 ] = '\0';

strcpy( *to, from.c_str( ) );
}

int
createSocket ( int *s )
{
struct sockaddr_in name;

if ( ( *s = socket( AF_INET, SOCK_STREAM, 0 ) ) < 0 )
{
cerr<<"Server: Socket"<<"\n";
}

name.sin_family = AF_INET;
name.sin_port = htons( (unsigned short int) PORT );
name.sin_addr.s_addr = htonl( INADDR_ANY );
if ( bind( *s, ( struct sockaddr * ) &name, sizeof( name ) ) < 0 )
{
cerr<<"Could not bind to socket."<<"\n";
exit( 1 );
}

return *s;
}

void *
serveClient( void *clientState )
{
int c;
int rc = 0;
char readbuf[ 2 ];
char message[ ] = "Message to client";//( char * ) malloc( 300 * sizeof( char ) );
struct client *mystate = ( struct client * ) clientState;

/* Set socket tot NONBLOCKING */
if( fcntl( mystate->socket , F_SETFL, O_NONBLOCK ) == -1 )
{
perror( "fcntl" );
exit( 1 );
}

while ( true )
{
while ( ( rc = recv( mystate->socket, readbuf, 1 , 0 ) ) > 0 )
{
readbuf[ 1 ] = '\0';
cout<<readbuf<<"\n";
}
sendClient( message, &( mystate->socket ) );
}
}

int
listenUp ( int *s )
{
int i = 0;
int error = 0;
pthread_t clientIds[MAX_CLIENTS];
struct client clients[MAX_CLIENTS];
struct sockaddr_in fsaun[MAX_CLIENTS];
int fromlen[MAX_CLIENTS];

while ( i++ < MAX_CLIENTS )
clients[i].state = CLIENT_NOT_CONNECTED;

if ( listen( *s, 10 ) < 0 )
{
cerr<<"Could not listen on socket"<<"\n";
exit( 1 );
}

while ( true )
{
while ( ( clients[i++].state == CLIENT_CONNECTED && i < MAX_CLIENTS ) );

if ( ( clients[i].socket = accept(
*s,
( sockaddr * ) &fsaun[i],
( socklen_t * ) &fromlen[i] ) ) < 0 )
{
cerr<<"Could not accept connection "<<i<<"\n";
}
else
{
error = pthread_create(
&clients[i].tid,
NULL,
serveClient,
(void *)&clients[i]
);
}
i = 0;
}
}

void
killsignal( int param )
{
fprintf( stderr, "Disconnecting.\n" );
}

void
intsignal( int param )
{
fprintf( stderr, "Write error.\n" );
}

int
main ( )
{
signal( SIGKILL, killsignal );
signal( SIGINT, intsignal );

int mySock = createSocket( &mySock );
listenUp( &mySock );
}

最佳答案

您的服务器不断地向客户端发送数据。当您的客户端退出时,它还没有读取套接字上要读取的所有数据。

此条件将生成 TCP RST,当收到 TCP RST 时,*nixes 上的默认行为是将 SIGPIPE 信号传递给进程。 SIGPIPE 信号的默认行为是退出程序。

对于 TCP 服务器,忽略 SIGPIPE 信号是很常见的,SIGPIPE 忽略 write()/send() 将在提到的情况(客户端退出或关闭带有待处理数据的套接字)时返回错误,并将 errno 设置为 EPIPE

在服务器的 main() 中添加:

signal(SIGPIPE,SIG_IGN);

可以找到更多信息here

关于c++ - 为什么我的客户端会杀死我的服务器?,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/5207152/

26 4 0
Copyright 2021 - 2024 cfsdn All Rights Reserved 蜀ICP备2022000587号
广告合作:1813099741@qq.com 6ren.com