网络编程的学习笔记

工作中三角形法则 1.技术,2.管理(管理自己的时间)3.沟通

基础内容

1.网络基础

2.TCP/IP协议

3.IP地址

4.Socket通信(TCP/UDP)

网络的基础概念



网络通信协议


网络通信分层:

分层模型:

数据在网络之间的传输要实现数据的封装和拆分



ip提供了一个巨大的贡献:ip给每台机器一个独一无二的地址(四个字节来代表一个ip,所以最大的ip不会超过255) IPV4 ip地址:网络段+主机号 a类网,第一个字段是固定的,例如192.是固定的,后面的3个位数都是不固定的,所有有256*256*256,B类网,第一个字段和第二个字段是固定的,例如192.168是固定的,后面两位是可选的,256*256,C类网,第一个字段和第二,第三个字段都固定192.168.10,所有只有256个网址可以用   。子网掩码中凡是为1的都是网络id,凡是为0 的都是主机id,子网掩码可以分内网,网关一般是连两处的   PS:若想了解网络的底层,可以看《TCP/IP详解》

两种机器通话方式

1.TCP(可靠的传输机制),三层握手机制  特点1:建立一个虚拟链接 2:默认传输会传输到 3:传输分前后,后一句不会比前一句先到(网络转账)。必须有回应的

2.UDP(不可靠的传输机制)(网络视频),可以丢包  ,直接说一句,不管是否有回应


java的socet(插座)  TCP中的client端是socket。TCP的customer端是ServerSocket,端口号是用来区分同一台机器上的不同的应用程序,一台机器最多可以有65536个应用程序

若自己的程序要定义端口号最好用1024以上的端口,1024以下的端口可能被系统占用,端口号分为Tcp端口和UDP端口,各个端口可以跑65536个程序,其中TCP端口8888和UDP端口8888是不同的


端口占用的错误:两个程序占用同一个端口

TCP通信模型:

sever程序

//运行时应该先启动server,然后再启动client,,记住,server和client是配套使用的
import java.net.*;
import java.io.*;
public class TcpServer
{
	public static void main(String[] args) throws Exception{
		ServerSocket ss = new ServerSocket(6666);//不间断的执行,在等待server的链接,通过6666端口来新建
		while(true){
		Socket s = ss.accept();//接受与否由server端来决定,若没有客户端连接,则会一直等待
        DataInputStream dis = new DataInputStream(s.getInputStream());//输入管
		System.out.println(dis.readUTF());//readUTF()是阻塞式的,除非对方写了东西过来才会有回应,accept()方法也是阻塞式的
		dis.close();
		s.close();
		}
		
	}
}
client程序

//运行时应该先启动server,然后再启动client,,记住,server和client是配套使用的
import java.net.*;
import java.io.*;
public class TcpServer
{
	public static void main(String[] args) throws Exception{
		ServerSocket ss = new ServerSocket(6666);//不间断的执行,在等待server的链接,通过6666端口来新建
		while(true){
		Socket s = ss.accept();//接受与否由server端来决定,若没有客户端连接,则会一直等待
        DataInputStream dis = new DataInputStream(s.getInputStream());//输入管
		System.out.println(dis.readUTF());//readUTF()是阻塞式的,除非对方写了东西过来才会有回应,accept()方法也是阻塞式的
		dis.close();
		s.close();
		}
		
	}
}

一端读,一端写

/*简单的client/server程序
源文件名称:TestServer.java/TestClient.java
要点:
1.java socket编程步骤
2.Socket/ServerSocket类用法
3.通过Socket对象可以获取通信对方Socket的信息
*/
import java.net.*;
import java.io.*;
public class TestServer
{
	public static void main(String[] args){
		try
			{
		ServerSocket ss = new ServerSocket(8888);
		while(true){
			
			Socket s = ss.accept();//等待客户端通信
			OutputStream os = s.getOutputStream();//建立输出管道
			DataOutputStream dos = new DataOutputStream(os);
			dos.writeUTF("客户端的端口号是:"+s.getPort()+",客户端的ip地址是:"+s.getInetAddress());
			dos.flush();
			dos.close();
			s.close();
			}
			}
			catch (Exception e)
			{
				e.printStackTrace();
			}
			

			
		


	}
}

/*简单的client/server程序
源文件名称:TestServer.java/TestClient.java
要点:
1.java socket编程步骤
2.Socket/ServerSocket类用法
3.通过Socket对象可以获取通信对方Socket的信息
*/
import java.net.*;
import java.io.*;
public class TestClient
{
	public static void main(String[] args){
		try
		{
			Socket s = new Socket("127.0.0.1",8888);
		DataInputStream dis = new DataInputStream(s.getInputStream());
		System.out.println(dis.readUTF());
		dis.close();
         s.close();
		}
		catch (Exception e)
		{
			e.printStackTrace();
		}
		
	}
}
一端又读,又写

import java.net.*;
import java.io.*;
public class TestSocketServer
{
	public static void main(String[] args){
		OutputStream os = null;
		InputStream is = null;
		try
		{
			ServerSocket ss = new ServerSocket(5888);//设置接听端口
			Socket s = ss.accept();
			os = s.getOutputStream();
			is = s.getInputStream();
			DataOutputStream dos = new DataOutputStream(os);//发消息到客户端(写出)
			DataInputStream dis = new DataInputStream(is);//接收客户端的消息(读入)
			String s1 = dis.readUTF();

			//server端先从client读一个数据,然后在写数据到client端口
			if(null!=s){
				System.out.println(s1);
				System.out.println("客户端端口号:"+s.getPort());
				System.out.println("客户端的地址是:"+s.getInetAddress());
			}
			//发消息到客户端
			dos.writeUTF("hi, client");
			dis.close();
			dos.close();
			s.close();

		}
		catch (Exception e)
		{
			e.printStackTrace();
		}
	}
}
客户端也是又读又写:

import java.net.*;
import java.io.*;
public class TestSocketClient
{
	public static void main(String[] args){
		OutputStream os = null;
		InputStream is = null;
		try
		{
			Socket s = new Socket("127.0.0.1",5888);//建立连接
			os = s.getOutputStream();
			is = s.getInputStream();
			DataOutputStream dos = new DataOutputStream(os);
			DataInputStream dis = new DataInputStream(is);
			//由于在server端是先读后写,所以在client端必须要先写后读,如果两个都是先读后写的话,那两个程序都会在哪里傻傻等待

			dos.writeUTF("hi server");
			String s1 = dis.readUTF();
			if(s1!=null){
			System.out.println(s1);
			dos.close();
			dis.close();
			//socket一定要记得关闭,如果不关闭,就会出现这样的问题 java.net.SocketException: Connection reset或者是java.io.EOFException错误
			s.close();
			}
		}
		catch (Exception e)
		{
			e.printStackTrace();
		}
	}
}

开通两个端口之后运行的结果如下图


聊天模式,客户端说一句,服务器端必须要回应一句,,这个运行结果很有趣,自己还不是太懂里面的知识,多看两遍

import java.net.*;
import java.io.*;
public class TalkServer
{
	public static void main(String[] args){
		try
		{
			ServerSocket ss = new ServerSocket(4700);
			Socket s = ss.accept();//等待客户端的连接
			BufferedReader br = new BufferedReader(new InputStreamReader(
				s.getInputStream()));//建立从客户端读消息
			PrintWriter pw = new PrintWriter(s.getOutputStream());//输出管道,写消息到客户端
			BufferedReader sin = new BufferedReader(new InputStreamReader(System.in));//从键盘中读消息
			//server是先读后写,所以对应到client端是先写后读  这里的是先从客户端读一行,然后显示出来,然后从自己的命令行读一行,然后写到client端
			System.out.println("client:"+br.readLine());//从客户端读一行
			String line = sin.readLine();
			while(!line.equals("bye")){
				//若没有从键盘中输入bye的时候
				pw.println(line);//将line写到客户端。
				pw.flush();
				System.out.println("Server:"+line);
				System.out.println("Client:"+br.readLine());//从客户端中再读一行
				line = sin.readLine();//从键盘中再读一行
			}
			br.close();
			pw.close();
			sin.close();
			s.close();
			ss.close();
		}
		catch (Exception e)
		{
			e.printStackTrace();
		}
	}
}
client端

import java.net.*;
import java.io.*;
public class TalkClient
{
	public static void main(String[] args){
		try
		{
			Socket s = new Socket("127.0.0.1",4700);
			BufferedReader br = new BufferedReader(new InputStreamReader(System.in));
			PrintWriter pw = new PrintWriter(s.getOutputStream());
			BufferedReader bis = new BufferedReader(new InputStreamReader(s.getInputStream()));
			String readLine = null;
			readLine = br.readLine();
			while(!readLine.equals("bye")){
				pw.println(readLine);
				pw.flush();
				System.out.println("client:"+readLine);
				System.out.println("SERVER:"+bis.readLine());
				readLine = br.readLine();
			}
			br.close();
			pw.close();
			bis.close();
			s.close();


		}
		catch (Exception e )
		{
			e.printStackTrace();
		}
		
	}
}

UDP:效率高,不可靠,(下面的程序是将一个字符串在客户端和服务器端进行传输)

import java.net.*;
public class TestUDPServer
{
	public static void main(String[] args) throws Exception{
		byte[]  buf = new byte[1024];
		DatagramPacket dp = new DatagramPacket(buf,buf.length);//新建了一个包裹对象,
		//这个包裹才是用来接收对方UDP发过来的东西,但是在包裹里面实际上是buf接收,且数据存在buf中。具体占所有的buf
		DatagramSocket ds = new DatagramSocket(5678);
		while(true){
			ds.receive(dp);//等对方发数据。只要有人发数据。socket就会将包袱仍在dp中
			System.out.println(new String(buf,0,dp.getLength()));///包袱中实际收了多少数据,string构造方法通过某一个字节数组的一部分构建成为一个字符串,然后打印出来

		}
	}
}


import java.net.*;
public class TestUDPClient
{
	public static void main(String[] args){
		try
		{
			byte[] buf = (new String("hello")).getBytes();//将一个字符串解析成一个字节数组
			DatagramPacket dp = new DatagramPacket(buf,buf.length,new InetSocketAddress("127.0.0.1",5678));//将字节数组中的所有的内容都发送出去。UDP本身是没有连接,写地址的原因是对于每一个UDP包都要写地址
			//,才能知道要将该包发送到哪里去
			DatagramSocket ds = new DatagramSocket(9999);//client端口占据9999端口,用这个端口向server端口为5678的发送包裹
			ds.send(dp);
			ds.close();
		}
		catch (Exception e)
		{
		}
	}
}

在服务器端和客户端传输一个long类型的值

import java.net.*;
import java.io.*;
public class TestUDPClient
{
	public static void main(String[] args){
		try
		{
			//将一个long类型的数发送到服务端
			long n = 10000L;
			ByteArrayOutputStream bos = new ByteArrayOutputStream();
             //将long类型的数写到bos中
			 DataOutputStream dos = new DataOutputStream(bos);
			 dos.writeLong(n);
			 byte[] buf = bos.toByteArray();      
			DatagramPacket dp = new DatagramPacket(buf,buf.length,new InetSocketAddress("127.0.0.1",5678));//将字节数组中的所有的内容都发送出去。UDP本身是没有连接,写地址的原因是对于每一个UDP包都要写地址
			//,才能知道要将该包发送到哪里去
			DatagramSocket ds = new DatagramSocket(9999);//client端口占据9999端口,用这个端口向server端口为5678的发送包裹
			ds.send(dp);
			ds.close();
		}
		catch (Exception e)
		{
		}
	}
}

import java.net.*;
import java.io.*;
public class TestUDPServer
{
	public static void main(String[] args) throws Exception{
		byte[]  buf = new byte[1024];
		DatagramPacket dp = new DatagramPacket(buf,buf.length);//新建了一个包裹对象,
		//这个包裹才是用来接收对方UDP发过来的东西,但是在包裹里面实际上是buf接收,且数据存在buf中。具体占所有的buf
		DatagramSocket ds = new DatagramSocket(5678);
		while(true){
			ds.receive(dp);//等对方发数据。只要有人发数据。socket就会将包袱仍在dp中
			//接收传过来的byte[]然后转为long类型
			ByteArrayInputStream bais = new ByteArrayInputStream(buf);
			DataInputStream dis = new DataInputStream(bais);
			System.out.println(dis.read());///包袱中实际收了多少数据,string构造方法通过某一个字节数组的一部分构建成为一个字符串,然后打印出来

		}
	}
}




  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值