前往小程序,Get更优阅读体验!
立即前往
发布
社区首页 >专栏 >Socket编程

Socket编程

作者头像
用户9184480
发布2024-12-19 08:52:44
发布2024-12-19 08:52:44
10800
代码可运行
举报
文章被收录于专栏:云计算linux云计算linux
运行总次数:0
代码可运行

Socket编程

ip和端口号:???

IP和端口号组成网络地址

IP(Internet Protocol),网络之间互连的协议,IP地址是区分不同计算机的唯一标识

端口号是计算机逻辑通讯接口,不同的应用程序用不同的端口,网络应用程序的区分标识

代码语言:javascript
代码运行次数:0
复制
端口号一般使用2个字节(16bit)进行编号,最多可以有65536个端口,只有整数,范围是从0 到65535
        第一类:公认端口(Well Known Ports):从0到1023,它们紧密绑定(binding)于一些服务。通常这些端口的通讯明确表明了某种服务的协议,例如:80端口实际上总是HTTP通讯。

? 第二类:注册端口(Registered Ports):从1024到49151。它们松散地绑定于一些服务。也就是说有许多服务绑定于这些端口,这些端口同样用于许多其它目的。例如:许多系统处理动态端口从1024左右开始。

? 第三类:动态和/或私有端口(Dynamic and/or Private Ports):从49152到65535。理论上,不应为服务分配这些端口。实际上,机器通常从1024起分配动态端口

TCP与UDP:

网络7层协议:物理层,数据链路层,网络层,传输层,会话层,表示层,应用层

传输层的两个主要协议

TCP(Transmission Control Protocol)协议:传输控制协议,提供可靠无差错的数据传输,速度慢,占用系统资源高

UDP(User Datagram Protocol)协议:用户数据报协议,不可靠的数据传输,速度快,较安全。

Socket编程原理(基于TCP):

服务器端

(1) 创建ServerSocket对象,绑定监听端口;

(2) 通过accept()方法监听客户端请求;

(3) 连接建立后,通过输入流读取客户端发送的请求信息;

(4) 通过输出流向客户端发送相应信息;

(5) 关闭响应资源。

客户端

(1) 创建Socket对象,指明需要连接的服务器地址和端口;

(2) 连接建立后,通过输出流向服务器端发送请求信息;

(3) 通过输入流获取服务器端返回的响应信息;

(4) 关闭响应资源。

具体代码实现:

简单示例:

服务器:

try {

ServerSocket server = new ServerSocket(9000);

System.out.println(“服务器已经运行,等待客户端信息!”);

Socket socket = server.accept();

BufferedReader in = new BufferedReader(

new InputStreamReader(socket.getInputStream()));

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

out.flush();

String clientMsg=in.readLine();

System.out.println(“客户端说:”+clientMsg);

out.println(“你好客户端:我是服务器,你的消息已经收到!”);

} catch (IOException e) {

e.printStackTrace();

}finally{

}

客户端:

Socket socket=null;

PrintWriter out=null;

BufferedReader reader=null;

try {

socket = new Socket(“127.0.0.1”,9000);

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

//print和write 重写了抽象类Writer里面的write方法

out.println(“你好服务器:我是客户端”);

out.flush();

reader = new BufferedReader(

new InputStreamReader(socket.getInputStream()));

String serverMsg=reader.readLine();

System.out.println(“服务器回话:”+serverMsg);

} catch (Exception e) {

e.printStackTrace();

} finally{

try {

out.close();

reader.close();

socket.close();

}

catch (IOException e)

{e.printStackTrace(); }

}

模拟聊天:

服务器:

try {

ServerSocket serverSocket= new ServerSocket(9000);

Socket socket = serverSocket.accept();

BufferedReader br = new BufferedReader(new InputStreamReader(socket.getInputStream()));

Scanner sc = new Scanner(System.in);

PrintWriter printWriter =new PrintWriter(socket.getOutputStream(),true);

while(true){

String s = br.readLine();

System.out.println(“客户端说:”+s);

if(s.contains(“借钱”)){

printWriter.println(“你被拉入黑名单”);

break;

}

String next = sc.next();

printWriter.println(next);

printWriter.flush();

}

} catch (IOException e) {

// TODO Auto-generated catch block

e.printStackTrace();

}

客户端:

try {

Socket s=new Socket(“127.0.0.1”,9000);

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

Scanner sc = new Scanner(System.in);

BufferedReader bufferedReader = new BufferedReader(new InputStreamReader(s.getInputStream()));

while(true){

String next = sc.next();

pw.println(next);

pw.flush();

String s1 = bufferedReader.readLine();

System.out.println(“服务器说:”+s1);

if(s1.contains(“黑名单”)){

break;

}

}

代码语言:javascript
代码运行次数:0
复制
} catch (UnknownHostException e) {
    // TODO Auto-generated catch block
    e.printStackTrace();
  } catch (IOException e) {
    // TODO Auto-generated catch block
    e.printStackTrace();
  }

UDP程序原理

客户端:?

??? 1) 创建客户端 DatagramSocket 类 + 指定的发送端口?

??? 2) 准备数据 以字节数组的形式?

??? 3) 打包 DatagramPacket+服务器端的地址和端口?

??? 4) 发送?

??? 5) 释放资源

服务器端?

??? 1) 创建服务端 DatagramSocket 类 + 指定的接收端口?

??? 2) 准备接收数据的容器 以字节数组的形式封装为DatagramPacket?

??? 3) 包 接收数据?

??? 4) 分析?

??? 5) 释放资源

主要类及方法:

DatagramSocket类主要用于实现信息的发送和接收 。主要方法如下:

public DatagramSocket()

构造DatagramSocket对象,不指定监听的端口

public DatagramSocket(int port)

构造DatagramSocket对象,同时指定监听的端口

public void send (DatagramPacket p)

发送数据报

public void receive(DatagramPacket p)

接收数据报

DatagramPacket类用于包装需要发送或接收的信息

public DatagramPacket(byte[] buf,int length)

用来接收长度为 length 的数据包,length 参数必须小于等于 buf.length

public DatagramPacket(byte[]

buf,int? length,InetAddress

address,int port)

构造数据报包,用来将长度为 length 的包发送到指定主机上的指定端口号

public byte[] getData()

返回接收数据

public int getLength()

返回要发送或接收数据的长度

具体代码实现:

示例代码:

服务器端:

DatagramSocket ds = null;

byte[] buf = new byte[1024];

try {

ds = new DatagramSocket();

String info = “hello qy71…”;

DatagramPacket dp= new DatagramPacket(info.getBytes(), info.getBytes().length,

InetAddress.getByName(“localhost”), 3000);

ds.send(dp);

} catch (Exception e) {

e.printStackTrace();

}finally{

ds.close();

}

客户端:

DatagramSocket ds = null;

byte[] buf = new byte[1024];

try {

ds = new DatagramSocket(3000);

DatagramPacket dp = new DatagramPacket(buf,1024);

ds.receive(dp);

String str = new String(buf,0,dp.getLength());

System.out.println(“收到消息:”+str);

}catch(Exception e){

e.printStackTrace();

}finally{

ds.close();

}

注意事项:先启动客户端,receive方法在接收到数据报前一直阻塞。再运行服务器端。

总结:

TCP和UDP是Java网络编程中的传输方式。TCP提供两台计算机之间可靠无差错的数据传输,但资源消耗较大,性能和效率较低;UDP不保证可靠数据的传输,但资源消耗小,性能和效率较高。在实际网络编程中建议根据系统的特点和需要,具体选择合适的方式

本文参与 腾讯云自媒体同步曝光计划,分享自作者个人站点/博客。
原始发表:2022-02-09,如有侵权请联系 cloudcommunity@tencent.com 删除

本文分享自 作者个人站点/博客 前往查看

如有侵权,请联系 cloudcommunity@tencent.com 删除。

本文参与 腾讯云自媒体同步曝光计划  ,欢迎热爱写作的你一起参与!

评论
登录后参与评论
0 条评论
热度
最新
推荐阅读
领券
问题归档专栏文章快讯文章归档关键词归档开发者手册归档开发者手册 Section 归档