用户注册



邮箱:

密码:

用户登录


邮箱:

密码:
记住登录一个月忘记密码?

发表随想


还能输入:200字

小蜜锋    -  云代码空间

—— 技术宅拯救世界!

Java Socket编程(服务器与客户端通信)

2012-12-27|4514阅||

摘要:第一步 充分理解Socket 1.什么是socket 所谓socket通常也称作"套接字",用于描述IP地址和端口,是一个通信链的句柄。应用程序通常通过"套接字"向网络发出请求或者应答网络请求。 以 J2SDK-1.3为例,Socket和ServerSocket

第一步 充分理解Socket
1.什么是socket
所谓socket通常也称作"套接字",用于描述IP地址和端口,是一个通信链的句柄。应用程序通常通过"套接字"向网络发出请求或者应答网络请求。
以 J2SDK-1.3为例,Socket和ServerSocket类库位于java.net包中。ServerSocket用于服务器端,Socket是 建立网络连接时使用的。在连接成功时,应用程序两端都会产生一个Socket实例,操作这个实例,完成所需的会话。对于一个网络连接来说,套接字是平等 的,并没有差别,不因为在服务器端或在客户端而产生不同级别。不管是Socket还是ServerSocket它们的工作都是通过SocketImpl类 及其子类完成的。
重要的Socket API:
java.net.Socket继承于java.lang.Object,有八个构造器,其方法并不多,下面介绍使用最频繁的三个方法,其它方法大家可以见JDK-1.3文档。
.Accept方法用于产生"阻塞",直到接受到一个连接,并且返回一个客户端的Socket对象实例。"阻塞"是一个术语,它使程序运行暂时"停留"在这个地方,直到一个会话产生,然后程序继续;通常"阻塞"是由循环产生的。
.getInputStream方法获得网络连接输入,同时返回一个IutputStream对象实例,。
.getOutputStream方法连接的另一端将得到输入,同时返回一个OutputStream对象实例。
注意:其中getInputStream和getOutputStream方法均会产生一个IOException,它必须被捕获,因为它们返回的流对象,通常都会被另一个流对象使用。
2.如何开发一个Server-Client模型的程序
开发原理:
服务器,使用ServerSocket监听指定的端口,端口可以随意指定(由于1024以下的端口通常属于保留端口,在一些操作系统中不可以随意使用,所以建议使用大于1024的端口),等待客户连接请求,客户连接后,会话产生;在完成会话后,关闭连接。
客户端,使用Socket对网络上某一个服务器的某一个端口发出连接请求,一旦连接成功,打开会话;会话完成后,关闭Socket。客户端不需要指定打开的端口,通常临时的、动态的分配一个1024以上的端口。
{建立服务器} 
import java.net.*;
import java.io.*;
public class Server
{
	private ServerSocket ss;
	private Socket socket;
	private BufferedReader in;
	private PrintWriter out;
	public Server()
	{
		try
		{
			ss = new ServerSocket ( 10000 );
			while ( true )
			{
				socket = ss.accept();
				in = new BufferedReader ( new InputStreamReader ( socket.getInputStream() ) );
				out = new PrintWriter ( socket.getOutputStream(),true );
				String line = in.readLine();
				out.println ( "you input is :" + line );
				out.close();
				in.close();
				socket.close();
			}
			ss.close();
		}
		catch ( IOException e )
			{}
	}
	public static void main ( String[] args )
	{
		new Server();
	}
}


这个程序建立了一个服务器,它一直监听10000端口,等待用户连接。在建立连接后给客户端返回一段信息,然后结束会话。这个程序一次只能接受一个客户连接。
{建立客户端} 
import java.io.*;
import java.net.*;
public class Client
{
	Socket socket;
	BufferedReader in;
	PrintWriter out;
	public Client()
	{
		try
		{
			socket = new Socket ( "xxx.xxx.xxx.xxx", 10000 );
			in = new BufferedReader ( new InputStreamReader ( socket.getInputStream() ) );
			out = new PrintWriter ( socket.getOutputStream(),true );
			BufferedReader line = new BufferedReader ( new InputStreamReader ( System.in ) );
			out.println ( line.readLine() );
			line.close();
			out.close();
			in.close();
			socket.close();
		}
		catch ( IOException e )
			{}
	}
	public static void main ( String[] args )
	{
		new Client();
	}
}


这个客户端连接到地址为xxx.xxx.xxx.xxx的服务器,端口为10000,并从键盘输入一行信息,发送到服务器,然后接受服务器的返回信息,最后结束会话。
 
第二步 多个客户同时连接
在实际的网络环境里,同一时间只对一个用户服务是不可行的。一个优秀的网络服务程序除了能处理用户的输入信息,还必须能够同时响应多个客户端的连接请求。在java中,实现以上功能特点是非常容易的。
设计原理:
主程序监听一端口,等待客户接入;同时构造一个线程类,准备接管会话。当一个Socket会话产生后,将这个会话交给线程处理,然后主程序继续监听。运用Thread类或Runnable接口来实现是不错的办法。
{实现消息共享} 
import java.io.*;
import java.net.*;
public class Server extends ServerSocket
{
	private static final int SERVER_PORT = 10000;
	public Server() throws IOException
	{
		super ( SERVER_PORT );
		try
		{
			while ( true )
			{
				Socket socket = accept();
				new CreateServerThread ( socket );
			}
		}
		catch ( IOException e )
			{}
		finally
		{
			close();
		}
	}
//--- CreateServerThread
	class CreateServerThread extends Thread
	{
		private Socket client;
		private BufferedReader in;
		private PrintWriter out;
		public CreateServerThread ( Socket s ) throws IOException
		{
			client = s;
			in = new BufferedReader ( new InputStreamReader ( client.getInputStream(), "GB2312" ) );
			out = new PrintWriter ( client.getOutputStream(), true );
			out.println ( "--- Welcome ---" );
			start();
		}
		public void run()
		{
			try
			{
				String line = in.readLine();
				while ( !line.equals ( "bye" ) )
				{
					String msg = createMessage ( line );
					out.println ( msg );
					line = in.readLine();
				}
				out.println ( "--- See you, bye! ---" );
				client.close();
			}
			catch ( IOException e )
				{}
		}
		private String createMessage ( String line )
		{
			xxxxxxxxx;
		}
	}
	public static void main ( String[] args ) throws IOException
	{
		new Server();
	}
}


这 个程序监听10000端口,并将接入交给CreateServerThread线程运行。CreateServerThread线程接受输入,并将输入回 应客户,直到客户输入"bye",线程结束。我们可以在createMessage方法中,对输入进行处理,并产生结果,然后把结果返回给客户。
 
第三步 实现信息共享:在Socket上的实时交流
网络的伟大之一也是信息共享,Server可以主动向所有Client广播消息,同时Client也可以向其它Client发布消息。下面看看如何开发一个可以实时传递消息的程序。
设计原理:
服务器端接受客户端的连接请求,同时启动一个线程处理这个连接,线程不停的读取客户端输入,然后把输入加入队列中,等候处理。在线程启动的同时将线程加入队列中,以便在需要的时候定位和取出。
{源码} 
import java.io.*;
import java.net.*;
import java.util.*;
import java.lang.*;
public class Server extends ServerSocket
{
	private static ArrayList User_List = new ArrayList();
	private static ArrayList Threader = new ArrayList();
	private static LinkedList Message_Array = new LinkedList();
	private static int Thread_Counter = 0;
	private static boolean isClear = true;
	protected static final int SERVER_PORT = 10000;
	protected FileOutputStream LOG_FILE = new FileOutputStream ( "d:/connect.log", true );
	public Server() throws FileNotFoundException, IOException
	{
		super ( SERVER_PORT );
		new Broadcast();
//append connection log
		Calendar now = Calendar.getInstance();
		String str = "[" + now.getTime().toString() + "] Accepted a connection1512";
		byte[] tmp = str.getBytes();
		LOG_FILE.write ( tmp );
		try
		{
			while ( true )
			{
				Socket socket = accept();
				new CreateServerThread ( socket );
			}
		}
		finally
		{
			close();
		}
	}
	public static void main ( String[] args ) throws IOException
	{
		new Server();
	}
//--- Broadcast
	class Broadcast extends Thread
	{
		public Broadcast()
		{
			start();
		}
		public void run()
		{
			while ( true )
			{
				if ( !isClear )
				{
					String tmp = ( String ) Message_Array.getFirst();
					for ( int i = 0; i < Threader.size(); i++ )
					{
						CreateServerThread client = ( CreateServerThread ) Threader.get ( i );
						client.sendMessage ( tmp );
					}
					Message_Array.removeFirst();
					isClear = Message_Array.size() > 0 ? false : true;
				}
			}
		}
	}
//--- CreateServerThread
	class CreateServerThread extends Thread
	{
		private Socket client;
		private BufferedReader in;
		private PrintWriter out;
		private String Username;
		public CreateServerThread ( Socket s ) throws IOException
		{
			client = s;
			in = new BufferedReader ( new InputStreamReader ( client.getInputStream() ) );
			out = new PrintWriter ( client.getOutputStream(), true );
			out.println ( "--- Welcome to this chatroom ---" );
			out.println ( "Input your nickname:" );
			start();
		}
		public void sendMessage ( String msg )
		{
			out.println ( msg );
		}
		public void run()
		{
			try
			{
				int flag = 0;
				Thread_Counter++;
				String line = in.readLine();
				while ( !line.equals ( "bye" ) )
				{
					if ( line.equals ( "l" ) )
					{
						out.println ( listOnlineUsers() );
						line = in.readLine();
						continue;
					}
					if ( flag++ == 0 )
					{
						Username = line;
						User_List.add ( Username );
						out.println ( listOnlineUsers() );
						Threader.add ( this );
						pushMessage ( "[< " + Username + " come . in >]" );
					}
					else
					{
						pushMessage ( "<" + Username + ">" + line );
					}
					line = in.readLine();
				}
				out.println ( "--- See you, bye! ---" );
				client.close();
			}
			catch ( IOException e )
				{}
			finally
			{
				try
				{
					client.close();
				}
				catch ( IOException e )
					{}
				Thread_Counter--;
				Threader.remove ( this );
				User_List.remove ( Username );
				pushMessage ( "[< " + Username + " left>]" );
			}
		}
		private String listOnlineUsers()
		{
			String s ="-+- .line list -+-1512";
			for ( int i = 0; i < User_List.size(); i++ )
			{
				s += "[" + User_List.get ( i ) + "]1512";
			}
			s += "-+---------------------+-";
			return s;
		}
		private void pushMessage ( String msg )
		{
			Message_Array.addLast ( msg );
			isClear = false;
		}
	}
}





这就是程序运行后,多用户登陆并且输入信息后的屏幕。实现了信息的实时广播。用户输入"l"就可以列出在线人员表。
顶 12踩 1收藏
文章评论
    发表评论

    个人资料

    • 昵称: 小蜜锋
    • 等级: 高级设计师
    • 积分: 7088
    • 代码: 757 个
    • 文章: 360 篇
    • 随想: 211 条
    • 访问: 1261 次
    • 关注

    标签

    设计模式(4)java(9)命名规范(2)广告创意(1)愤怒的小鸟(1)游戏(5)jsp(1)配置(1)Surface(1)windows(1)javabean(1)设计方法(1)开发工具(2)web(4)大数据(2)GPU(1)硬盘(1)内部结构(1)黑客(1)窃取(1)编码(1)解决方法(1)php(28)mysql(9)数据库备份(1)数据库还原(1)命令(2)数据库(1)安装(1)2012(2)世界末日(3)仙剑5前传(1)默哀(1)电源(1)女生(1)装饰器模式(2)古剑奇谭(1)电脑桌(1)史上最牛(1)编程语言(2)小米(3)电视机顶盒(1)营销策略(1)Android(8)手势(1)诺亚方舟(1)Eclipse(1)汽车(1)操作系统(1)软件(1)互联网(5)大事记(1)设计师(2)壁纸(1)古剑奇谭2(1)古剑奇谭网络版(1)云计算(2)服务器(1)框架(2)Socket(1)jquery(1)构造函数执行顺序(1)火车票(1)3D(1)数据中心(2)正则表达式(2)Web前端(1)开发框架(1)系统瘫痪(1)12306(2)cpu(1)javascript(2)开发日记(15)体育馆管理系统(15)网页设计(1)CSS3(3)腾讯(3)小游戏(1)interface(1)平板(2)面试(2)设计(5)摄影(2)数据挖掘(1)钢琴谱(1)情人节(1)陈欧体(1)程序员(3)漫画(1)UserAgent(1)iPhone(2)NoSQL(1)ui(9)越狱(1)指南(1)abstract(1)css(3)git(2)八核(2)三星(1)linux(11)数据类型(1)html5(2)UML(2)perftools(1)创意(1)logo(1)色谱(1)响应式(5)Metro(2)虚拟机(1)jvm(1)垃圾回收(1)left(1)join(1)连接查询(1)溯源系统(1)Override(1)SAE(2)WordPress(1)指针(1)链表(1)系统分析师(1)中间件(1)corba(1)static(1)无线(1)监控(1)iPad(1)Apache(2)比特币(2)命名规则(1)手机支付(1)curl(3)笔记(1)导航(1)thinkphp(1)异常导致本地路径泄漏(1)web设计(1)网络安全(1)诗句(1)4K对齐(1)代码库(1)色彩(1)动画片(1)struts2(3)漏洞(5)确认框(1)心情驿站(1)ArscEditor(1)resources.(1)apktool(1)AppKey(1)新浪微博(1)app(5)广告(3)赚钱(1)响应式布局(1)html(1)淘宝(2)微信(1)重构(5)缓存(1)破解(1)后门(1)七夕(1)SEO(2)概念设计(1)面向对象(1)bootstrap(1)性能(2)优化(1)iis(1)爬虫(1)采集(1)算法(2)文本相似度(2)cto(1)js(1)fsockopen(1)扁平化设计(2)网页(1)心情(7)小米电视(1)开箱(1)励志(2)招聘(3)命名(1)notepad++(1)python(1)配色(3)扁平化(4)ps(2)搞笑(2)创业(3)渲染(1)电影(1)模板(1)微博(1)企业家(1)公司(1)总结(1)前端(1)运营(1)变形(1)svn(4)教程(3)搜狗(1)泄密(1)双11(1)天猫(1)UC(1)启动界面(1)光棍节(1)双十一(2)物流(1)备份(1)更新(1)插入(1)插件(2)jsTree(1)(1)海量数据(1)分辨率(1)草图(1)手绘(1)速度(1)文本处理(1)实习(1)感想(1)文件(1)简历(1)65.49.2.17(1)yum(1)解决办法(1)阿里云(2)推广(1)来往(1)春运(1)LBS(1)gb2312(1)utf-8(1)log4j(1)详解(1)收购(1)私服(1)TortoiseGi(1)post(1)异常(2)flappyBird(1)应用创新大赛(1)宙斯杯(1)学习方法(1)xp(1)退役(1)安全(1)技术贴(1)flash(1)刷机(1)京东(1)电商(1)Tomcat(1)JDK(1)免费(1)长投影(1)图标(1)Photoshop(1)云端集成开发环境(1)软件开发(1)可视化(1)工具(2)OpenSSL(1)Heartbleed(1)vsftp(1)中国知网(1)学术论文(1)免费下载(1)开发(1)手册(1)速查表(1)追随战略(1)sdk(1)文章(1)发布(1)文件管理(1)沙画(1)动效(2)原型(1)感悟人生(1)哲理(1)Bash(1)类图(1)知识管理(1)Console(1)调试命令(1)rpm(1)报错(1)挂载(1)数据盘(1)云主机(1)产品经理(1)原型设计(1)mql4(1)mt4(1)ea(1)程序化交易(1)CURLOPT_PO(1)阿里云​(1)CentOS6(2)OpenSSH(1)漏洞修复(2)升级(1)安骑士(1)链克(1)

    站长推荐