黑马程序员_网络编程

 
 
------------- android培训java培训、java博客、java学习型技术博客、期待与您交流! -------------
网络编程 通过使用套接字来达到进程间通信目的的编程就是网络编程 通信的条件 1、找到对方IP 2、数据要发送到对方指定的应用程序上,为了标识这些应用型程序,   所以给这些网络应用都用数字进行标识,为了方便称呼这个数字,叫逻辑端口 3、定义通信规则,这个通信规则称为协议(按照同一种规则通讯) 通讯三要素 IP地址: 网络中设备的标识,本地回环地址:127.0.0.1 默认主机名:localhost 对应对象,InetAddress 端口号: 用于标识进程的逻辑地址,不同进程的标识 有效端口:0-65535,其中0-1024被系统程序所保留 就是一个数值,没有必要封装对象 传输协议 UDP:User Datagram Protocol;面向无连接 分发送端 和接收端 将数据及源和目的 封装成数据包中,不需要建立连接 每个数据包的大小限制在64k内 因为无连接,是不可靠协议 不需要建立连接,速度快 TCP:Transmission Control Protocol,面向连接 Socket和ServerSocket,客户端和服务端 建立连接,形成传输数据的通道 在连接中进行大数据量传输 通过三次握手完成连接,是可靠协议 必须建立连接,效率会稍低 Socket套接字 Socket就是为网络服务提供的一种机制 通信的两端都有Socket 网络通信其实就是Socket间的通信 数据在两个Socket间通过IO传输 IP地址 InetAddress 此类表示互联网协议IP地址 方法 static InetAddress getLocalHost()      返回本地主机 static InetAddress getByName(String host)  在给定主机名的情况下确定主机的IP地址 static InetAddress[] getAllByName(String host)   ...返回ip地址数组 String getHostAddress()  返回ip地址字符串   String getHostName()     返回ip地址的主机名 UDP协议 public class DatagramSocket 此类表示用来发送和接受数据报包的套接字 public class DatagramPacket 此类表示数据报包 发送端 1、建立UDPsocket服务,通过DatagramSocket对象 2、提供数据,并将数据封装到数据包中 3、通过socket服务的send方法,将数据包发出去 4、关闭资源 接收端 1、定义udpsocket服务,通常会监听一个端口,其实就是给这个接受网络应用程序定义数字标识,  方便明确哪些数据过来是该应用程序处理的 2、定义一个数据包,因为要存储接收到的字节数据,  因为数据包对象中有更多功能可以提取字节数据中的不同数据信息 3、通过socket服务的receive方法将收到的数据存入已定义好的数据包中 4、通过数据包对象的特有功能,获取数据 5、关闭资源 TCP协议 public class Socket  此类实现客户端套接字 public class ServerSocket  此类实现服务器套接字 客户端 1、创建Socket服务,并指定要连接的主机和端口 2、获取Socket中的输出流向外发送数据 3、获取Socket中的输入流读取客户端反馈信息 4、关闭客户端 服务端 1、建立服务端的socket服务,ServerSocket();并监听一个端口, 2、获取连接过来的客户端对象 通过ServerSokcet的accept方法,没有连接就会等,这个方法是阻塞式的 3、客户端如果发过来数据,服务端要使用对应的客户端对象,   获取到该客户端对象的读取流来读取客户端发过来的数据 4、如需反馈服务端信息,则获取服务端写入流写入数据 5、关闭服务端(可选) 分类演示
import java.net.*;
class  IPDemo
{
	public static void main(String[] args)throws Exception 
	{
		InetAddress i = InetAddress.getLocalHost();
		//返回:主机名/字面值IP地址的字符串表示形式
		System.out.println(i.toString());
		System.out.println(i.getHostName());
		System.out.println(i.getHostAddress());

		//在给定主机名的情况下确定主机的IP地址
		InetAddress ia = InetAddress.getByName("www.baidu.com");
		InetAddress ia2 = InetAddress.getByName("119.75.217.56");
		
		System.out.println("address:"+ia.getHostAddress());
		System.out.println("name:"+ia.getHostName());

		InetAddress[] iarr = InetAddress.getAllByName("www.baidu.com");
		for(InetAddress inet : iarr)
		{
			System.out.println("baidu:"+inet.toString());
		}
	}
}
//UDP传输过程简单演示
import java.net.*;
class UdpSend
{
	public static void main(String[] args)throws Exception 
	{
		//创建udp服务,通过DatagramSocket对象
		DatagramSocket ds = new DatagramSocket(); 

		//确定数据,并封装成数据包;  DatagramPacket(byte[] buf,int length,InetAddress address , int port)
		byte[] buf= "udp ge men lai le".getBytes();
		DatagramPacket dp = new DatagramPacket(buf,buf.length,InetAddress.getByName("192.168.1.108"),10000);
		
		//通过socket服务,将已有的数据包发送出去,通过send方法
		ds.send(dp);

		//关闭资源
		ds.close();
	}
}
class UdpRece
{
	public static void main(String[] args)throws Exception
	{
		//创建udp socket服务,建立端点
		DatagramSocket ds = new DatagramSocket(10000);//建立监听10000端口
		
		//定义数据包,用于存储数据
		byte[] buf = new byte[1024];
		DatagramPacket dp = new DatagramPacket(buf,buf.length);
		
		//通过服务的receive方法将收到数据存入数据包中
		ds.receive(dp);
		//通过数据包的方法获取其中的数据
		String ip = dp.getAddress().getHostAddress();
		String data = new String(dp.getData(),0,dp.getLength());		
		
		int port = dp.getPort();

		System.out.println(ip+":"+data+"::"+port);

		//关闭资源
		ds.close();
	}
}
/*
UDP传输,需求获取键盘录入,并定义结束语句,
*/
import java.net.*;
import java.io.*;
class  UdpSend2
{
	public static void main(String[] args) throws Exception
	{
		DatagramSocket ds = new DatagramSocket();
		BufferedReader bufr = new BufferedReader(new InputStreamReader(System.in));
		String line = null;
		//readLine阻塞方法,等着键盘录入一行包括行终止符
		while ((line=bufr.readLine())!=null)
		{
			if ("886".equals(line))
				break;
		
			byte[] buf = line.getBytes();
		
			DatagramPacket dp = new DatagramPacket(buf,buf.length,InetAddress.getByName("192.168.1.108"),8888); 
			//IP地址最后一段有两个不能用.0和.255,前者代表网络段,后者代表给1-254所有群发
			ds.send(dp);
		}

		ds.close();
	}
}
class UdpReceive2
{
	public static void main(String[] args)throws Exception
	{
		//此处不能放入循环中,否则会发生绑定异常,因为new多个服务,在一个端口上(上个服务端口还未在内存中释放)
		DatagramSocket ds = new DatagramSocket(8888); 	
		while(true)
		{
			byte[] buf = new byte[1024];
			DatagramPacket dp = new DatagramPacket(buf,buf.length);
			ds.receive(dp);//此方法为阻塞式方法,有就接受,没有就等待,不会死循环

			String ip = dp.getAddress().getHostAddress();
			String data = new String(dp.getData(),0,dp.getLength());//注意到这里写长度
			
			System.out.println(ip+" :  "+data);
		}
	}
}

/*
编写一个聊天程序
有收数据的部分,和发数据的部分,这两部分需要同时执行,

因为收和发动作是不一致的,所以要定义两个run方法
并将这个两个方法封装到两个不同类中
两个run方法中内容就是上面演示示例内容

*/

import java.io.*;
import java.net.*;
class  Send implements Runnable
{
	private DatagramSocket ds;
	Send(DatagramSocket ds)
	{
		this.ds = ds;
	}
	public void run()
	{
		try
		{
			BufferedReader bufr = new BufferedReader(new InputStreamReader(System.in));		
			String line = null;
			while ((line=bufr.readLine())!=null)
			{
				if("886".equals(line))
					break;
				byte[] buf = line.getBytes();
				DatagramPacket dp = new DatagramPacket(buf,buf.length,InetAddress.getByName("192.168.1.108"),10001);		
				ds.send(dp);
			}
		}
		catch(Exception e)
		{}
	}
}
class  Rece implements Runnable
{
	private DatagramSocket ds;
	Rece(DatagramSocket ds)
	{
		this.ds=ds;
	}
	public void run()
	{
		try
		{
			while(true)
			{
				byte[] buf = new byte[1024];
				DatagramPacket dp = new DatagramPacket(buf,buf.length);
				
				ds.receive(dp);
				String id = dp.getAddress().getHostAddress();
				
				String data = new String(dp.getData(),0,dp.getLength());

				System.out.println(id+" :: "+data);
			}
		}
		catch(Exception e)
		{}
	}
}
class Chat
{
	public static void main(String[] args)throws Exception
	{
		DatagramSocket ds = new DatagramSocket();
		DatagramSocket ds1 = new DatagramSocket(10001);

		new Thread(new Send(ds)).start();
		new Thread(new Rece(ds1)).start();

	}
}

import java.io.*;
import java.net.*;
class TcpClient
{
	public static void main(String[] args) throws Exception
	{
		//创建客户端的Socket服务,指定目的主机和端口
		Socket s = new Socket("192.168.1.108",10003);
		
		//为了发送数据,应该获取socket流中的输出流
		OutputStream out = s.getOutputStream();

		out.write("tcp ge men lai le".getBytes());

		s.close();
	}
}
class TcpServer
{
	public static void main(String[] args)throws Exception
	{
		//建立服务端socket服务,并监听一个端口,
		ServerSocket ss = new ServerSocket(10003);

		//通过accept方法获取连接过来的客户端对象
		Socket s = ss.accept();  //阻塞方法
		
		//若有客户端连接进来,就显示某某ip已连接上
		String ip = s.getInetAddress().getHostAddress();
		System.out.println(ip+"......connected");
		
		//获取客户端发送过来的数据,那么要使用客户端对象的读取流来读取数据
		InputStream in = s.getInputStream();
		
		byte[] buf = new byte[1024];
		int len = in.read(buf);
		
		System.out.println(new String(buf,0,len));

		s.close();
	}
}

/*
演示tcp的传输的客户端和服务端的互访
需求:客户端给服务端发送数据,服务端收到后,给客户端反馈信息
*/
import java.net.*;
import java.io.*;
class  TcpClient2
{
	public static void main(String[] args)throws Exception
	{
		Socket s = new Socket("192.168.1.108",10004);
		InputStream in = s.getInputStream();
		OutputStream out = s.getOutputStream();

		out.write("服务端,你好".getBytes());
		
		byte[] buf = new byte[1024];
		int len = in.read(buf);
		
		System.out.println(new String(buf,0,len));
		s.close();
	}
}
class TcpServer2
{
	public static void main(String[] args)throws Exception
	{
		ServerSocket ss = new ServerSocket(10004);

		Socket s = ss.accept();
		
		String ip = s.getInetAddress().getHostAddress();
		System.out.println(ip+".....connected");

		InputStream  in = s.getInputStream();
		byte[] buf = new byte[1024];
		int len = in.read(buf);
		System.out.println(new String(buf,0,len));

		OutputStream out = s.getOutputStream();

		out.write("哥们收到,你也好".getBytes());

		s.close();
		ss.close();
	}
}

/*
需求:建立一个文本转换服务器,客户端给服务端发送文本,服务端会将文本转成大写在返回给客户端,
而且客户端可以不断的进行文本转换,当客户端输入over时,转换就会结束
*/
import java.io.*;
import java.net.*;
class Client
{
	public static void main(String[] args)throws Exception
	{
		Socket s = new Socket("192.168.1.108",10004);
		BufferedReader bufr = new BufferedReader(new InputStreamReader(System.in));
		BufferedReader in = new BufferedReader(new InputStreamReader(s.getInputStream()));

		PrintWriter out = new PrintWriter(s.getOutputStream(),true);
		String line = null;
		while ((line=bufr.readLine())!=null)
		{
			if("over".equals(line))
				break;
			out.println(line);
		
			System.out.println(in.readLine());

		}

		bufr.close();
		s.close();
	}
}
class Server
{
	public static void main(String[] args)throws Exception
	{
		ServerSocket ss = new ServerSocket(10004);
		Socket s =ss.accept();
		
		String ip = s.getInetAddress().getHostAddress();
		System.out.println(ip+"is connected..");
		BufferedReader in = new BufferedReader(new InputStreamReader(s.getInputStream()));
		PrintWriter out = new PrintWriter(s.getOutputStream(),true);
		String line = null;
		while ((line=in.readLine())!=null)
		{
			out.println(ip+": "+line.toUpperCase());
			
		}
		s.close();
		ss.close();
	}
}

/*
TCP,客户端传输数据到服务端,并接受服务端反馈信息
客户端定义输入流读取数据,然后使用Socket中输出流进行缓存,
服务端使用接受的Socket对象,获取其输入流读取数据,然后定义输出流将得到数据存储,
完毕后,使用客户端Scoket对象输出流写入反馈信息
客户端使用Socket对象中输入流读取反馈信息
*/
import java.io.*;
import java.net.*;
class  TextClient
{
	public static void main(String[] args)throws Exception 
	{
		Socket s = new Socket("192.168.1.108",10006);

		BufferedReader bufr = new BufferedReader(new FileReader("IPDemo.java"));

		PrintWriter out = new PrintWriter(s.getOutputStream(),true);

		String line = null;
		while ((line=bufr.readLine())!=null)
		{
			out.println(line);
		}
		s.shutdownOutput();//关闭客户端的输出流,相当于给流中加入一个结束标记-1

		BufferedReader in = new BufferedReader(new InputStreamReader(s.getInputStream()));
		String str = in.readLine();   //若无关闭,此处在读,等待
		System.out.println(str);

		s.close();
		bufr.close();
	}
}
class TextServer
{
	public static void main(String[] args)throws Exception
	{
		ServerSocket ss = new ServerSocket(10006);
		Socket s = ss.accept();
		String id = s.getInetAddress().getHostAddress();
		System.out.println(id+".....is connected");

		PrintWriter pw = new PrintWriter(new FileOutputStream("copy_IPDemo.txt"),true);
		BufferedReader in = new BufferedReader(new InputStreamReader(s.getInputStream()));
		
		String line = null;
		while ((line=in.readLine())!=null) //等待,所以要结束
		{
			pw.println(line);
		}
		
		PrintWriter out = new PrintWriter(s.getOutputStream(),true);
		out.println("上传成功");

		s.close();
		ss.close();
		pw.close();
	}
}

/*

上述示例服务端都有个局限性,当一个客户端连接上以后,被服务端获取,服务端执行具体流程
这时其他客户端连接,只有等待
因为服务端还没有处理完A客户端的请求,还未结束本次循环回路执行下次accpet方法
所以暂时获取不到B客户端对象

那么为了可以让多个客户端同时并发访问服务端
那么服务端最好就是将每个客户端封装到一个单独的线程中,这样就可以同时处理多个客户

演示: 并发上传+判断条件,+覆盖文件处理
*/

import java.io.*;
import java.net.*;
class PicClient
{
	public static void main(String[] args)throws Exception
	{
		File file = new File(args[0]);
		//给传输的文件进行条件设置
		if (args.length!=1)
		{
			System.out.println("only one JPG file");
			return;
		}
		if (!(file.exists()&&file.isFile()))
		{
			System.out.println("file is not exists or error");
			return;
		}
		if (!file.getName().endsWith(".jpg"))
		{
			System.out.println("wrong format,please choose jpg format");
			return;
		}
		if(file.length()>1024*1024*10)
		{
			System.out.println("File is too big to load");
			return;
		}

		method(file);	
	}
	public static void method(File file)throws Exception
	{
		Socket s = new Socket("192.168.1.108",10006);
		FileInputStream fis = new FileInputStream(file);
		OutputStream out = s.getOutputStream();
		byte[] buf = new byte[1024];
		int len = 0;
		while ((len=fis.read(buf))!=-1)
		{
			out.write(buf,0,len);
		}
		s.shutdownOutput();
		
		InputStream in = s.getInputStream();
		byte[] buf2 = new byte[1024];
		int num = in.read(buf);
		System.out.println(new String(buf,0,num));

		fis.close();
		s.close();
	}
}
class PicThread
{
	public static void main(String[] args)throws Exception
	{
		ServerSocket ss = new ServerSocket(10006);
		while (true)
		{
			Socket s = ss.accept();	
			new Thread(new PicServer(s)).start();
		}
	}
}
class PicServer implements Runnable
{
	private Socket s;
	PicServer(Socket s)
	{
		this.s = s;
	}
	public void run()
	{
		int count =1;
		String ip = s.getInetAddress().getHostAddress();
		System.out.println(ip+"...is connected");
		
		try
		{
			//用ip地址进行文件区分,若文件名一样则复制但不替换,文件名改为文件名(n)
			File file = new File(ip+"("+count+")"+".jpg");
			while(file.exists())
				file = new File(ip+"("+(count++)+")"+".jpg");
			
			FileOutputStream fos = new FileOutputStream(file);
			InputStream in = s.getInputStream();
			byte[] buf = new byte[1024];
			int len = 0;
			while ((len=in.read(buf))!=-1)
			{
				fos.write(buf,0,len);
			}
			fos.close();

			OutputStream out =  s.getOutputStream();
			out.write("succeded to upload".getBytes());		
		}
		catch (Exception e)
		{
			throw new RuntimeException("faied to load");
		}
	}
}



------------- android培训java培训、java博客、java学习型技术博客、期待与您交流! -------------
详情请查看:http://edu.csdn.net/heima/
### 黑马程序员计算机网络课程及相关资料 黑马程序员作为一家知名的IT培训机构,在其课程体系中涵盖了广泛的IT技术领域,其中包括计算机网络相关内容。以下是关于计算机网络课程及其相关资源的详细介绍: #### 1. **计算机网络基础** 马程序员的计算机网络课程通常会从基础知识入手,讲解OSI七层模型以及TCP/IP协议栈的核心概念[^4]。这些内容帮助学员理解数据在网络中的传输过程。 #### 2. **Socket编程** 在网络编程部分,课程可能会涉及Python或其他语言下的Socket通信机制。通过学习Socket API,学生可以掌握如何创建客户端和服务端程序来实现基本的数据交换功能[^2]。 下面展示了一个简单的基于Python的Socket服务端与客户端交互的例子: ```python import socket # 创建一个服务器套接字 server_socket = socket.socket(socket.AF_INET, socket.SOCK_STREAM) host = 'localhost' port = 9999 server_socket.bind((host, port)) server_socket.listen(5) while True: client_socket, addr = server_socket.accept() print(f'连接地址: {addr}') message = '感谢连接该服务器' + '\r\n' client_socket.send(message.encode('utf-8')) client_socket.close() ``` #### 3. **HTTP协议详解** HTTP协议是Web开发的重要组成部分之一,也是计算机网络课程的重点章节。课程可能深入探讨GET/POST请求方式的区别、状态码含义等内容,并结合实际案例分析浏览器是如何向服务器发起请求并获取响应的过程[^5]。 #### 4. **网络安全** 此外,针对现代互联网环境下的安全威胁,如SQL注入攻击、XSS跨站脚本攻击等问题也会有所提及,教导开发者采取适当措施保护应用程序免受恶意行为侵害[^6]。 #### § 相关问题 § 1. 如何利用Python编写一个多线程版的Socket服务器? 2. OSI参考模型各层次的功能是什么?它和TCP/IP四层结构有何异同之处? 3. 前端页面加载过程中经历了哪些主要阶段?涉及到哪些计算机网络原理? 4. 使用HTTPS代替HTTP有哪些优势?SSL/TLS证书的工作流程是怎么样的? 5. 如果想进一步提高自己的计算机网络知识水平,除了参加培训之外还可以阅读哪些经典书籍或者在线文档呢?
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值