⭐ 欢迎来到虫虫下载站! | 📦 资源下载 📁 资源专辑 ℹ️ 关于我们
⭐ 虫虫下载站

📄 network.c

📁 Linux游戏编程源码
💻 C
字号:
#include <stdio.h>#include <stdlib.h>#include <unistd.h>#include <sys/socket.h>#include <arpa/inet.h>#include <string.h>#include <errno.h>#include <netdb.h>#include "network.h"void CreateNetPacket(net_pkt_p pkt, player_p player, int firing, int hit){    /* Fill in all of the relevant values, calling       our conversion macro to preclude endianness       problems. */    pkt->my_x = DOUBLE_TO_NET(player->world_x);    pkt->my_y = DOUBLE_TO_NET(player->world_y);    pkt->my_angle = DOUBLE_TO_NET(player->angle);    pkt->my_velocity = DOUBLE_TO_NET(player->velocity);    pkt->fire = (Uint8)firing;    pkt->hit = (Uint8)hit;}void InterpretNetPacket(net_pkt_p pkt,			double *remote_x, double *remote_y,			double *remote_angle, double *remote_velocity,			int *firing, int *hit){    /* Decode the values in the packet and store       them in the appropriate places. */    *remote_x = NET_TO_DOUBLE(pkt->my_x);    *remote_y = NET_TO_DOUBLE(pkt->my_y);    *remote_angle = NET_TO_DOUBLE(pkt->my_angle);    *remote_velocity = NET_TO_DOUBLE(pkt->my_velocity);    *firing = (int)pkt->fire;    *hit = (int)pkt->hit;}int ConnectToNetgame(char *hostname, int port, net_link_p link){    int sock;    struct sockaddr_in addr;    struct hostent *hostlist;    /* Resolve the host's address with DNS. */    hostlist = gethostbyname(hostname);    if (hostlist == NULL || hostlist->h_addrtype != AF_INET) {	fprintf(stderr, "Unable to resolve %s: %s\n",		hostname,		strerror(errno));	return -1;    }	    /* Save the dotted IP address in the link structure. */    inet_ntop(AF_INET, hostlist->h_addr_list[0], link->dotted_ip, 15);    /* Load the address structure with the server's info. */    memset(&addr, 0, sizeof (struct sockaddr_in));    addr.sin_family = AF_INET;    memcpy(&addr.sin_addr, hostlist->h_addr_list[0], hostlist->h_length);    addr.sin_port = htons(port);    /* Create a TCP stream socket. */    sock = socket(PF_INET, SOCK_STREAM, IPPROTO_TCP);    if (sock < 0) {	fprintf(stderr, "Unable to create socket: %s\n",		strerror(errno));	return -1;    }	    printf("Attempting to connect to %s:%i...\n",	   link->dotted_ip, port);    /* Ready to go! Connect to the remote machine. */    if (connect(sock, (struct sockaddr *)&addr, sizeof (addr)) < 0) {	fprintf(stderr, "Unable to connect: %s\n",		strerror(errno));	close(sock);	return -1;    }    /* Copy the socket and the address into the link structure. */    link->sock = sock;    link->addr = addr;    printf("Connected!\n");    return 0;}int WaitNetgameConnection(int port, net_link_p link){    int listener, sock;    struct sockaddr_in addr;    socklen_t addr_len;    /* Create a listening socket. */    listener = socket(PF_INET, SOCK_STREAM, IPPROTO_IP);    if (listener < 0) {	fprintf(stderr, "Unable to create socket: %s\n",		strerror(errno));	return -1;    }    /* Set up the address structure for the listener. */    addr_len = sizeof (addr);    memset(&addr, 0, addr_len);    addr.sin_family = AF_INET;    addr.sin_port = htons(port);    addr.sin_addr.s_addr = htonl(INADDR_ANY);    /* Bind the listener to a local port. */    if (bind(listener, &addr, addr_len) < 0) {	fprintf(stderr, "Unable to bind to port %i: %s\n",		port, strerror(errno));	close(listener);	return -1;    }    /* Make this a listening socket. */    if (listen(listener, 1) < 0) {	fprintf(stderr, "Unable to listen: %s\n",		strerror(errno));	close(listener);	return -1;    }    printf("Waiting for connection on port %i.\n", port);    /* Accept a connection. */    if ((sock = accept(listener, (struct sockaddr *)&addr, &addr_len)) < 0) {	fprintf(stderr, "Unable to accept connection: %s\n",		strerror(errno));	close(listener);	return -1;    }    /* Ready to go! Save this info in the link structure. */    link->sock = sock;    link->addr = addr;    inet_ntop(AF_INET, &addr.sin_addr, link->dotted_ip, 15);	    printf("Connected!\n");    return 0;}int ReadNetgamePacket(net_link_p link, net_pkt_p pkt){    int remaining, count;    remaining = sizeof (struct net_pkt_s);    count = 0;    /* Loop until a complete packet arrives.       This could block indefinitely, but it       typically won't, and it's of less importance       since the networking code runs in a separate       thread. */    while (remaining > 0) {	int amt;	/* Read as much as possible. */	amt = read(link->sock, ((char *)pkt)+count, remaining);	/* If read returns a positive value, or zero	   with errno == EINTR, there is no error. */	if (amt <= 0 && errno != EINTR) {	    fprintf(stderr, "ReadNetgamePacket: read failed: %s\n",		    strerror(errno));	    return -1;	}			/* Increment the counters by the amount read. */	remaining -= amt;	count += amt;    }          return 0;}int WriteNetgamePacket(net_link_p link, net_pkt_p pkt){    int remaining, count;    remaining = sizeof (struct net_pkt_s);    count = 0;    /* Loop until we've written the entire packet. */    while (remaining > 0) {	int amt;	/* Try to write the rest of the packet.	   Note the amount that was actually written. */	amt = write(link->sock, ((char *)pkt)+count, remaining);	/* Same error semantics as ReadNetgamePacket. */	if (amt <= 0 && errno != EINTR) {	    fprintf(stderr, "WriteNetgamePacket: read failed: %s\n",		    strerror(errno));	    return -1;	}			/* Increments the counters by the number of	   bytes written. */	remaining -= amt;	count += amt;    }          return 0;}void CloseNetgameLink(net_link_p link){    /* Close the socket connection. */    close(link->sock);    link->sock = -1;}

⌨️ 快捷键说明

复制代码 Ctrl + C
搜索代码 Ctrl + F
全屏模式 F11
切换主题 Ctrl + Shift + D
显示快捷键 ?
增大字号 Ctrl + =
减小字号 Ctrl + -