• 连接主机Java网络编程(一) 一个简单的服务端/客户端应用程序


    新手发帖,很多方面都是刚入门,有错误的地方请大家见谅,迎欢批评指正

        在Java中,我们应用java.net.Socket及其关相类来成完有关络网的关相功能。Socket类非常简略易用,因为Java术技隐藏了建立络网连接和通过连接发送数据的杂复程过。面下所说的内容只适用于TCP协议。

        

        一、连接到服务器

        我们可以应用Socket类的构造函数来打开一个套接字,如

    Socket sk = new Socket("210.0.235.14",13);

        其中,210.0.235.14是一个点分十进制的String象对,表现目标主机的IP地址(或主机名), 13表现指定连接目标主机的13口端。这里的210.0.235.14是位于香港的一个时授服务器,时授服务器默许的口端一般都为13.

        注意,在功成连接到服务器之前,序程会阻塞。

        

        接下来可以应用Socket类的getInputStream()方法来失掉一个InputStream象对,通过这个象对就能够取得到目标主机给我们发过来的息信:

    InputStream inStream = sk.getInputStream();

        同理,要向目标主机发送数据,则可以调用getOutputStream()方法来取得一个出输流象对。

        

        面下的例子功能是连接时授服务器,并将返回的息信打印到标准出输中:

    try
    {
    Socket sk = new Socket("210.0.235.14",13);
    sk.setSoTimeout(3000);
    			InputStream inStream = sk.getInputStream(); //失掉输入流象对
    			Scanner sc = new Scanner(inStream);
    			
    			//将数据打印到控制台
    			while(sc.hasNextLine())
    			{
    				String str = sc.nextLine();
    				System.out.println("Output : " + str);
    			}
    			
    			sk.close();
    		
    		}
    		catch(SocketTimeoutException e) //时超异常
    		{
    			System.out.println("Time Out!");
    		}
    		catch(Exception e)
    		{
    			e.printStackTrace();
    		}

        码代中setSoTimeout()方法可以设置时超间时,即如果超过了设定间时还没有成完写读操纵,则会抛出SocketTimeoutException,可以通过获捕这个异常来闭关连接。

        另外还有一个时超问题是必要须处理的,就是这个Socket类的构造函数

        new Socket(host,port);

        会始终无穷地阻塞下去,直到功成建立了到目标主机的连接为止。这当然不是我们所希望的。我们可以通过如下调用方法处理此问题:

    Socket sk = new Socker();
    sk.connect(new InetSocketAddress(host,port),2000); //设置时超间时为2秒

        

        二、取得主机地址

        InetAddress类的静态方法getByName(hostname)可以返回代表了某个主机地址的InetAddress象对,这个象对闭封了一个4字节的序列,即主机的IP地址。然后再调用getHostAddress()方法返回一个表现IP地址的String象对.

        一些问访量大的主机名常通会对应着多个IP地址以实现负载均衡。我们可以调用getAllByName()方法来取得有所主机地址,该方法返回一个InetAddress象对的数组。

        面下是一个简略的小序程,实现的功能是,如果不在令命行中设置数参,就打印出当地的IP地址,如果指定了主机名,则打印出该主机有所的IP地址:

    package cls;
    
    import java.net.*;
    
    public class ShowIP
    {
    	public static void main(String[] args)
    	{
    		try
    		{
    			if(args.length > 0)
    			{
    				String hostName = args[0]; //主机名
    				InetAddress[] addr = InetAddress.getAllByName(hostName); //失掉该主机的有所地址
    				//打印出输至控制台
    				for(InetAddress address : addr)
    				{
    					System.out.println(address.getHostAddress());
    				}
    			}
    			else
    			{
    				System.out.println(InetAddress.getLocalHost().getHostAddress());
    			}
    		}
    		catch(Exception e)
    		{
    			e.printStackTrace();
    		}
    		
    	}
    
    }

        三、服务器端序程

        服务器端应用序程应用ServerSocket类来建创套接字,并钭其绑定至当地口端中,如

        每日一道理
    喜欢海,不管湛蓝或是光灿,不管平静或是波涛汹涌,那起伏荡漾的,那丝丝的波动;喜欢听海的声音,不管是浪击礁石,或是浪涛翻滚,那轻柔的,那澎湃的;喜欢看海,不管心情是舒畅的或是沉闷的,不管天气是晴朗的或是阴沉的,那舒心的,那松弛的……
    ServerSocket sock = new ServerSocker(8000);

        sock.accept()方法让序程不停地等待连接,该方法只有当有客户端连接时才会返回一个代表了新连接的Socket象对,即该方法会产生阻塞。

        这里一般要为个每连接新开启一个线程为其服务。

        

        面下是一个完全的例子,服务端在8400口端处等待连接,每当连接到来时,新开一个线程为其服务,并将连接息信写入的日志件文中:

    package cls;
    
    import java.io.*;
    import java.net.*;
    import java.util.*;
    
    public class ServerDemo
    {
    
    	/**
    	 * @param args
    	 */
    	public static void main(String[] args)
    	{
    		try
    		{
    			//ServerSocket servSocket = new ServerSocket(8000);
    			ServerSocket servSocket = new ServerSocket(8400);
    			
    			int amount = 0;
    			while(true)
    			{
    				Socket client = servSocket.accept();
    				
    				++amount;
    				Date time = new Date();
    				
    				String prompt = time.toString() + ": 第" + amount + "个用户 " + client.getInetAddress().getHostAddress() + " 已连接\n";
    				System.out.print(prompt); //在控制台出输息信
    				ServerDemo.writeLog(prompt); //写入到件文中
    				
    				//start a new Thread
    				Thread th = new Thread(new ServThread(client,amount));
    				th.start();
    			}
    		}
    		catch(Exception e)
    		{
    			e.printStackTrace();
    		}
    		
    	}
    	
    	//写入日志件文
    	public static void writeLog(String str)
    	{
    		File logFile = new File("server-log.txt");
    		try
    		{
    			FileWriter out = new FileWriter(logFile,true);
    			out.append(str);
    			out.close();
    			
    		}
    		catch(Exception e)
    		{
    			e.printStackTrace();
    		}
    	}
    
    }
    
    /*
     * 服务线程类
     */
    class ServThread implements Runnable
    {
    	private Socket client;
    	private int ix;
    	
    	public ServThread(Socket soc,int ix)
    	{
    		client = soc;
    		this.ix = ix;
    	}
    	public void run()
    	{
    		try
    		{
    			InputStream inStream = client.getInputStream();
    			OutputStream outStream = client.getOutputStream();
    			
    			Scanner recv = new Scanner(inStream);
    			PrintWriter send = new PrintWriter(outStream,true);
    			
    			send.println("迎欢~随意聊几句吧![输入'bye'闭关联接]");
    			while(recv.hasNextLine())
    			{
    				String str = recv.nextLine();
    				if(str.equals("bye"))
    				{
    					send.println("See you later ~ ^-^");
    					break;
    				}
    				send.println("这是个测试序程,在现还没有什么功能哦");
    			}
    			
    			Date time = new Date();
    			String prompt = time.toString() + ": 第" + ix + "个用户 " + client.getInetAddress().getHostAddress() + " 已断开连接\n";
    			System.out.print(prompt);
    			ServerDemo.writeLog(prompt); //写入到件文中
    			
    			client.close();
    		}
    		catch(Exception e)
    		{
    			e.printStackTrace();
    		}
    	}
    }

        这个序程已被放到了服务器上,大家可以应用telnet youthol.tk 8400 令命来验体一下这个序程的行运结果。。

        

    文章结束给大家分享下程序员的一些笑话语录: 与女友分手两月有余,精神萎靡,面带菜色。家人介绍一女孩,昨日与其相亲。女孩果然漂亮,一向吝啬的我决定破例请她吃晚饭。
    选了一个蛮贵的西餐厅,点了比较贵的菜。女孩眉开眼笑,与我谈得很投机。聊着聊着,她说:“我给你讲个笑话吧。”“ok”
      “一只螳螂要给一只雌蝴蝶介绍对象,见面时发现对方是只雄蜘蛛。见面后螳螂问蝴蝶‘如何?’,‘他长的太难看了’,‘别看人家长的丑,人家还有网站呢’。”
      “呵呵………”我笑。忽然她问:“你有网站吗?”  

  • 相关阅读:
    第九章、硬件抽象层:HAL
    第八章、让开发板发出声音:蜂鸣器驱动
    第七章、LED将为我闪烁:控制发光二极管
    第六章、第一个Linux驱动程序:统计单词个数
    第五章、搭建S3C6410开发板的测试环境
    Android深度探索(卷1)HAL与驱动开发
    第三次月考
    第二次月考
    Android深度探索(卷1)HAL与驱动开发
    第六章 集合运算
  • 原文地址:https://www.cnblogs.com/jiangu66/p/3061643.html
Copyright © 2020-2023  润新知