网络上两个程序通过一个双向的通信连接实现数据的交换,这双向链路的一端称为一个socket。用来实现不同的虚拟机或计算机之间的通信。java语言中,Socket可以分为两种类型:面向连接的(tcp传输控制协议),面向无连接的(udp用户数据报协议)。任何一个Socket都由端口号和IP地址唯一确定。
Socket编程,简单来讲就是通讯的两个端点都是Socket服务,网络通信就是Socket通信,而Socket服务之间的数据传输本质上都是IO流传输。socket是java.net包下的类,
二:TCP 客户端和服务端
基于TCP的通信:首先,Server服务器端Listen监听指定的某个端口是否有连接请求,其次Client客户端向Server端发送Connect连接请求,最后Server端向Client端发回Acept接受消息。
Socket和ServerScoket,建立客户端和服务端,建立连接后通过socket的IO流进行数据传输。通过查阅socket对象,发现在该对象建立时,就可以去连接指定主机。
客户端:创建socket服务(Socket),并指定要连接的主机和端口。
服务端:1创建socket服务(ServerSocket)2获取连接过来的客户端对象accept方法(阻塞式),
3客户端如果发来数据,服务端要使用对应的客户端对象,并获取对象的读取流读取数据。
public class TcpClient {//客户端
public static void main(String[] args) {
try {//1创建客户端的soclet服务,指定目的主机和端口
Socket s= new Socket("192.168.1.107",10003);
//2获取socket流中的输出流,3关闭
OutputStream out=s.getOutputStream();
out.write("tcpSabber".getBytes());
s.close();
} catch (Exception e) {e.printStackTrace(); }
}
}
public class TcpServer {//服务器端
public static void main(String[] args) {
try {
//建立服务器端socket服务,并监听一个端口
ServerSocket ss=new ServerSocket(10003);
//通过accept方法获取连接过来的客户端对象
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));
} catch (Exception e) {
e.printStackTrace();
}
}
}
package com.haibo.MySocket;
import java.io.InputStream;
import java.io.OutputStream;
import java.net.ServerSocket;
import java.net.Socket;
/**
* Created with IDEA.
* User:haibo.
* DATE:2018/6/22/022
*演示tcp的传输的客户端和服务端的互访。
*需求:客户端给服务端发送数据,服务端收到后,给客户端反馈信息。
*/
public class TcpDemo2 {
/*
客户端:
1,建立socket服务。指定要连接主机和端口。
2,获取socket流中的输出流。将数据写到该流中。通过网络发送给服务端。
3,获取socket流中的输入流,将服务端反馈的数据获取到,并打印。
4,关闭客户端资源。
*/
public static void main(String[] args)throws Exception {
Socket s = new Socket("192.168.1.254",10004);
OutputStream out = s.getOutputStream();
out.write("服务端,你好".getBytes());
InputStream in = s.getInputStream();
byte[] buf = new byte[1024];
int len = in.read(buf);
System.out.println(new String(buf,0,len));
s.close();
}
}
package com.haibo.MySocket;
import java.io.InputStream;
import java.io.OutputStream;
import java.net.ServerSocket;
import java.net.Socket;
/**
* Created with IDEA.
* User:haibo.
* DATE:2018/6/22/022
*/
public class TcpDemo2Serv {
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();
Thread.sleep(10000);
out.write("哥们收到,你也好".getBytes());
s.close();
ss.close();
}
}
一:udp 发送端和接收端
DatagramSocket类用来发送和接收数据报包的套接字。无连接包投递。
1通过udp方式将一段文字数据发送出去(建立udpscoket服务,提供数据,并将数据封装到数据包中,通过socket服务发送功能将数据包发出去,关闭资源)
public class UdpSend {//发送
public static void main(String[] args) {
try {//1通过udp服务,通过DatagramSocket对象。
DatagramSocket ds=new DatagramSocket();
//2确定数据,并封装成数据包
byte[] buf ="send Sabber".getBytes();
DatagramPacket dp=new DatagramPacket(buf,buf.length,InetAddress.getByName("192.168.1.107"),10000);
//3.通过socket服务,将已有的数据包发送出去。
ds.send(dp);
//4.关闭
} catch (Exception e) {}
}
}
public class UdpRece {//接收
public static void main(String[] args) {
try {//1.创建udpsocket服务,建立端点.监听一个接口
DatagramSocket ds=new DatagramSocket(10000);
//2.定义一个数据包存储接收到的字节数据。
while(true){
byte[] buf=new byte[1024];
DatagramPacket dp=new DatagramPacket(buf,buf.length);
//3.通过socket服务的receive方法将收到的数据出存入已定义好的数据包
ds.receive(dp);
//4.通过数据包对象的特有功能将不同的数据取出,打印到控制台
String ip=dp.getAddress().getHostAddress();
String data= new String(dp.getData(),0,dp.getLength());
int port=dp.getPort();
System.out.print(ip+data+port);
}
//5.关闭资源
// ds.close();
} catch (Exception e) {
e.printStackTrace();}
}
}
编写一个聊天程序:多线程技术,一个线程控制收一个控制发,
class UdpCart {
public static void main(String[] args) throws Exception {
DatagramSocket sendSocket = new DatagramSocket();
DatagramSocket receSocket = new DatagramSocket(10002);
new Thread(new Send(sendSocket)).start();
new Thread(new Rece(receSocket)).start();
}
static class Send implements Runnable {
private DatagramSocket ds;
public 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) {
byte[] buf = line.getBytes();
DatagramPacket dp =
new DatagramPacket(buf,buf.length, InetAddress.getByName("192.168.1.255"),10002);
ds.send(dp);
if("886".equals(line))
break;
}
}
catch (Exception e) {
throw new RuntimeException("发送端失败");
}
}
}
static class Rece implements Runnable {
private DatagramSocket ds;
public 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 ip = dp.getAddress().getHostAddress();
String data = new String(dp.getData(),0,dp.getLength());if("886".equals(data))
{
System.out.println(ip+"....离开聊天室");
break;
}
System.out.println(ip+":"+data);
}
}
catch (Exception e) {
throw new RuntimeException("接收端失败");
}
}
}}