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

📄 connection.c

📁 linux下支持P2P的客户端程序,采用了Gnutella的方法,其中有实现Gnutella的具体源码,是一个基于p2p环境下的音乐共享软件,有助于对P2P的研究
💻 C
字号:
/*-*-linux-c-*-*//* *  gnewtellium - Newtella for Unix *  Copyright (C) 2001 Elias Athanasopoulos * *  This program is free software; you can redistribute it and/or modify *  it under the terms of the GNU General Public License as published by *  the Free Software Foundation; either version 2 of the License, or *  (at your option) any later version. * *  This program is distributed in the hope that it will be useful, *  but WITHOUT ANY WARRANTY; without even the implied warranty of *  MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the *  GNU General Public License for more details. * *  You should have received a copy of the GNU General Public License *  along with this program; if not, write to the Free Software *  Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA  02111-1307  USA *//* These includes are needed in the specified   order by the BSD family. It maybe better to   add an #ifdef BSD or something here...*/#include <sys/types.h>#include <sys/socket.h>#include <netinet/in.h>#include <arpa/inet.h>#include <stdio.h>#include <stdlib.h>#include <sys/ioctl.h>#include <unistd.h>#include <fcntl.h>#include <time.h>#include <errno.h>#include <string.h>#include "global.h"#include "gui.h"#include "newtella.h"#include "connection.h"#include "hosts.h"#ifdef SOLARIS#include <sys/filio.h>#endifextern struct newtella_options *gl_options;extern int gl_server;extern struct host_info *gl_my_host_info;int bytes_avail(int s){	int ret;       	ioctl(s, FIONREAD, &ret);	return ret;}int con_recv_packet(struct newtella_connection *con, int len){  	int rval = recv(con->s, con->b, len, 0);	if (rval == 0 || (rval < 0 && errno != EAGAIN)) 		return 0;	else 		return rval;}void con_send_packet(struct newtella_connection *con, gchar *buf, gint len, gint maydrop){	struct gpacket *packet;	gint qlen;      	g_return_if_fail(con->s);	if (con->state == GS_FAILED || con->state == GS_TIMEOUT)		return;	/* we don't drop our packets */	if (!maydrop)		goto real_send;       	qlen = g_list_length(con->queue);      	/* drop packet if our queue is full */	if (qlen >= QUEUE_FULL && ((con->type == CT_OUTGOING) ||				   (con->type == CT_INCOMING))) 	{		con->total_dropped_to_send++;		goto skip;	} real_send:	packet = newtella_malloc(sizeof(struct gpacket));	packet->_time = time((time_t) NULL); 	packet->len   = len;	packet->data  = newtella_malloc(len);	memcpy(packet->data, buf, len);		con->queue = g_list_prepend(con->queue, packet); skip:	if (!con->write_tag)		con->write_tag = gdk_input_add(con->s, 					       GDK_INPUT_WRITE | GDK_INPUT_EXCEPTION, 					       (GdkInputFunction) newtella_write, 					       (gpointer) con);		return;	}int con_send_to_all(gchar *buf, gint len, gint maydrop){	GList *iter;	struct newtella_connection *con;	gint fwd = 0;        /* forward a packet to every alive con */	iter = g_list_first(gl_con);	while (iter) {		con = iter->data;				if (con->state == GS_CONNECTED) {			con_send_packet(con, buf, len, maydrop);			fwd++;		}		iter = g_list_next(iter);	}	return fwd;}int con_send_ex_one(struct newtella_connection *excon, gchar *buf, gint len, gint maydrop){	GList *iter;	struct newtella_connection *con;	if (!excon) {		con_send_to_all(buf, len, maydrop);		return 1;	}        /* forward a packet to every alive except con */	iter = g_list_first(gl_con);	while (iter) {		con = iter->data;				if (con->state == GS_CONNECTED && con->s != excon->s)  			con_send_packet(con, buf, len, maydrop);					iter = iter->next;	}	return 1;}void con_zero_stats(struct newtella_connection *con){	/* sent data */	con->total_sent             = 0;        con->total_dropped_to_send  = 0;	/* received data */        con->total_handled          = 0;        con->total_received_dropped = 0;        con->total_bad_received     = 0;}        void con_init_queue(struct newtella_connection *con){	/* init queue */	con->queue = NULL;}int con_add(guint32 ip, guint16 port){	/* add a new gnutella connection */	struct newtella_connection *new_con = newtella_malloc(sizeof(struct newtella_connection));		new_con->ip = ip;	new_con->port = port;		con_zero_stats(new_con);	con_init_queue(new_con);		new_con->state   = GS_WAITINGCONNECT;		new_con->type    = CT_OUTGOING;		gl_con = g_list_append(gl_con, new_con);	gui_add_con_to_list(new_con); 	new_con->s = newtella_force_connect(ip, port);		new_con->read_tag = gdk_input_add(new_con->s, GDK_INPUT_READ | GDK_INPUT_EXCEPTION, 		      (GdkInputFunction) newtella_read, (gpointer)new_con);		new_con->write_tag = gdk_input_add(new_con->s, GDK_INPUT_WRITE | GDK_INPUT_EXCEPTION, 		      (GdkInputFunction) newtella_connect, (gpointer)new_con);					/* update time */	new_con->last_time = time((time_t)NULL);		return 1;}int con_remove(struct newtella_connection *con){	GList *l;	struct gpacket *packet;	/* remove gdk i/o tags */	if (con->read_tag)		gdk_input_remove(con->read_tag);	if (con->write_tag)		gdk_input_remove(con->write_tag);		/* close socket */	close(con->s);	/* empty queue */	l = g_list_first(con->queue);		while (l) {		packet = l->data;		newtella_free(packet->data);		newtella_free(packet);		l = l->next;	}	g_list_free(con->queue);		/* remove it from GUI */	gui_remove_con_from_list(con);	/* remove it from the connection's list */	gl_con = g_list_remove(gl_con, con);	/* remove host */	host_remove(con->ip, con->port);			newtella_free(con);	return 1;}int con_mark(struct newtella_connection *con, con_state state){	switch (state) {	case GS_HOSTFEED:		con->state = GS_HOSTFEED;		gl_options->connected++;		break;	case GS_FAILED:		if (con->state == GS_FAILED || con->state == GS_TIMEOUT)			break;		if (con->state == GS_CONNECTED || con->state == GS_HOSTFEED)			gl_options->connected--;		con->state = GS_FAILED;				//if (con->type == CT_INCOMING || con->type == CT_OUTGOING)		//	gl_options->cons--;	        if (con->type == CT_UPLOAD) 			gl_options->ucons--;		else if (con->type == CT_DOWNLOAD)			gl_options->dcons--;		break;	case GS_TIMEOUT:		if (con->state == GS_TIMEOUT || con->state == GS_FAILED)			break;		if (con->state == GS_CONNECTED || con->state == GS_HOSTFEED)			gl_options->connected--;		con->state = GS_TIMEOUT;		//if (con->type == CT_INCOMING || con->type == CT_OUTGOING)		//	gl_options->cons--;	        if (con->type == CT_UPLOAD) 			gl_options->ucons--;		else if (con->type == CT_DOWNLOAD)			gl_options->dcons--;		break;	case GS_CONNECTED:		con->state = GS_CONNECTED;		gl_options->connected++;		break;	default:		break;	}		con->last_time = time((time_t)NULL);	gui_update_con_status(con);	return 1;}int con_reset_buffer(struct newtella_connection *con){	/* init buffer */	con->buffer_len = 0;//	con->b          = NULL;	return 1;}int con_activate(void){	GList *iter;	struct host_info *host;        	iter = g_list_first(gl_hosts_in_cache); 	while (iter) {		host = iter->data;		      		if (!host->used) {			host->used = 1;			con_add(host->ip, host->port);						if (gl_options->cons >= gl_options->min_con)				break;		}	       		iter = g_list_next(iter);	}		return 1;}

⌨️ 快捷键说明

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