/* New connection, but record it to name */ netconnection_t *net_rec_new_connection(int fd, char *name, demo_header header) { int size, demo_fd; netconnection_t *nc; if( !(demo_fd = open(name, O_RDWR | O_CREAT | O_TRUNC, 0644)) ) { perror("open"); return NULL; } HTONS( header.x_tiles ); HTONS( header.y_tiles ); HTONS( header.fps ); size = write( demo_fd, &header, sizeof(demo_header)); if( size != sizeof(demo_header) ) { printf("Couldn't write header information from \"%s\"\n", name); if( size < 0 ) perror("write"); else printf("Wrote only %d bytes of %d.\n", size, sizeof(demo_header)); close(demo_fd); return NULL; } if( (nc = net_new_connection(fd)) ) nc->record_fd = demo_fd; else close(demo_fd); return nc; }
static void socket_init(void) { //先连gated const char *gated_ip = config_get_string("GATED_IP"); int port = config_get_int("INTER_GATED_PORT"); int gated_fd = net_connect(gated_ip, port, 0); if (gated_fd < 0) { printf("fail to connect gated!!!\n"); exit(1); } g_gated_conn = net_new_connection(gated_fd, gated_read_cb, NULL, gated_error_cb); auth_packet_t authpack; authpack.cmd = AUTH_GAMED; authpack.len = sizeof(authpack); fprintf(stdout, "authpack.len = %d!!\n", authpack.len); int ret = net_send_packet(g_gated_conn, (void *)&authpack, sizeof(authpack)); fprintf(stdout, "ret = %d!!\n", ret); }
/* Add the client that's been accept()-ed onto fd */ static void sv_net_add_client(int fd) { netconnection_t *nc; client_t *cl; if( (nc = net_new_connection(fd)) == NULL ) { printf("Error creating new net connection.\n"); return; } if( (cl = (client_t *)malloc(sizeof(client_t))) == NULL ) { perror("malloc"); sv_netmsg_send_rejection(nc, "server memory error"); net_close_connection(nc); return; } /* Add client to the list */ if( cl_root == NULL ) cl_root = cl; if( cl_tail != NULL ) cl_tail->next = cl; cl->prev = cl_tail; cl->next = NULL; cl_tail = cl; cl->nc = nc; strncpy(cl->name, "Connecting Client", NETMSG_STRLEN); cl->status = CONNECTING; /* Waiting for join message */ cl->bad = 0; cl->ent = NULL; cl->keypress = 0; printf("Client joining from \"%s\"\n", nc->remote_address); }
int cl_network_connect(char *sv_name, int port) { struct hostent *hp; struct sockaddr_in addr; netmsg msg; demo_header header; int sock = -1; if( client.demo != DEMO_PLAY ) { /* A real connection, not just a demo */ memset(&addr, 0, sizeof(addr)); addr.sin_family = AF_INET; addr.sin_port = htons(port); if(!client.with_ggz) { sock = net_init_socket(); if( (addr.sin_addr.s_addr = inet_addr(sv_name)) == INADDR_NONE ) { if((hp = gethostbyname(sv_name)) == NULL) { close(sock); sock = -1; return 0; } else { addr.sin_addr.s_addr = *(long *) hp->h_addr; } } if( connect(sock, (struct sockaddr *) &addr, sizeof(addr)) < 0 ) { perror("connect"); close(sock); sock = -1; return 0; } } else { /* ggz mode */ signal(SIGPIPE, SIG_IGN); /* Ignore Pipe errors */ if( (sock = ggz_client_get_sock()) < 0 ) { sock = -1; return 0; } /* avoid perdig effect */ sleep(3); } } switch( client.demo ) { case DEMO_RECORD: printf("RECORDING Connection.......\n"); header.x_tiles = client.x_tiles; header.y_tiles = client.y_tiles; header.fps = client.fps; server = net_rec_new_connection(sock, client.demoname, header); break; case DEMO_PLAY: server = net_fake_connection(client.demoname, &header); client.x_tiles = header.x_tiles; client.y_tiles = header.y_tiles; client.view_w = client.x_tiles * TILE_W; client.view_h = client.y_tiles * TILE_H; break; case DEMO_NONE: default: server = net_new_connection(sock); } if( server == NULL ) { printf("Couldn't create new connection\n"); close(sock); sock = -1; return 0; } client.connected = 1; client.sv_status = JOINING; printf("Joining Game....\n"); cl_netmsg_send_join(); printf("Querying Server info......\n"); cl_netmsg_send_query_sv_info(); net_output_flush(server); /* FIXME: This alarm() does not work correctly */ alarm(10); /* Timeout after 10 secs */ signal(SIGALRM, sigcatcher); printf("Reading data from server...... "); while( net_input_flush(server, NM_ALL) > 0 ) { printf("Got something!\n"); while( (msg = net_next_message(server, NM_ALL)).type != NETMSG_NONE ) { if( msg.type == NETMSG_SV_INFO ) { /* Got server info ok, we can join the game */ alarm(0); cl_net_handle_message(msg); return 1; } else if(msg.type == NETMSG_REJECTION || msg.type == NETMSG_QUIT){ /* We were rejected or another error occured trying to join */ alarm(0); cl_net_handle_message(msg); return 0; } else if( client.debug ) { printf("IGNORING message type %d!\n", msg.type); } } } alarm(0); printf("TIMED OUT waiting for server info!\n"); cl_network_disconnect(); return 0; }
static void sv_net_update(void) { char buf[32]; struct timeval tv; struct sockaddr_in naddr; client_t *cl; netconnection_t *nc; fd_set read_fds; int newsock; int maxfd; /* Highest fd + 1 needed for select() */ int addrlen; /* addrlen is passed to accept() and is changed to be the length of the new address */ FD_ZERO(&read_fds); /* If status of sock changes, then we have a new client wishing to join the server */ FD_SET(sock, &read_fds); maxfd = sock; /* The fd's change status when there is new client data to be read */ for( cl = cl_root ; cl != NULL ; cl = cl->next ) { FD_SET(cl->nc->fd, &read_fds); if( cl->nc->fd > maxfd ) maxfd = cl->nc->fd; } tv.tv_sec = 0; tv.tv_usec = M_SEC / 20; select(maxfd + 1, &read_fds, 0, 0, &tv); if( FD_ISSET(sock, &read_fds) ) { if( server.with_ggz ) { if( xtuxggz_is_sock_set(&newsock) != 1 ) newsock=-1; else fprintf(stderr,"-----NEW PLAYER----\n"); } else { addrlen = sizeof(naddr); newsock = accept(sock,(struct sockaddr *)&naddr,(socklen_t *)&addrlen); } if( newsock < 0 ) { perror("accept"); } else { if( server.clients < server.max_clients ) { fcntl( newsock, F_SETFL, O_NONBLOCK); /* Set to non blocking */ sv_net_add_client(newsock); } else { /* Too many clients, send rejection */ snprintf(buf, 32, "Server full (max=%d)", server.max_clients); if( (nc = net_new_connection(newsock)) ) { sv_netmsg_send_rejection(nc, buf); net_close_connection(nc); } } } } /* Read data from each ACTIVE client if it's fd status has changed */ for( cl = cl_root ; cl != NULL ; cl = cl->next ) if( FD_ISSET(cl->nc->fd, &read_fds) ) cl->nc->incoming = 1; }