Socket就是为网络服务提供的一种机制。
通信两端都有Socket。
网络通信其实就是Socket通信。
数据在两个Socket间通过IO传输。
UDP使用DatagramSocket
发送端:
建立思路:
1,建立udpsocket服务
2,提供数据,并将数据封装成数据包。
3,通过socket服务的发送功能。
4,关闭资源。
import java.net.*;
class UDPSend
{
public static void main(String[] args) throws Exception
{
DatagramSocket ds = new DatagramSocket();
byte[] buf = "123hehe".getBytes();
DatagramPacket dp = new DatagramPacket(buf,buf.length,InetAddress.getByName("code-geass"),8000);
ds.send(dp);
ds.close();
}
}
接收端:
思路:
1,定义udpSocket服务。通常会监听一个端口。和发送端对应。
2,定义一个数据包,用于接收数据。数据包对象有更多功能提取字节数据中的不同数据。
3,通过socket服务的receive方法将接受到的数据存入定义好的数据包中。
4,通过数据包对象的特有功能。将不同的数据取出,打印在控制台上。
5,关闭资源。
import java.net.*;
class UDPRece
{
public static void main(String[] args) throws Exception
{
DatagramSocket ds = new DatagramSocket(8000);
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);
//ds.close();
}
}
键盘录入发送端:
BufferedReader bf = new BufferedReader(new InputStreamReader(System.in));
readLine数据并且封装成数据包发送出去。
import java.net.*;
import java.io.*;
class UDPDemo2
{
public static void main(String[] args) throws Exception
{
DatagramSocket ds =new DatagramSocket();
BufferedReader br = new BufferedReader(new InputStreamReader(System.in));
String line=null;
byte[] buf = null;
while((line=br.readLine())!=null)
{
if(line.equals("over"))
break;
buf= line.getBytes();
DatagramPacket dp= new DatagramPacket(buf,buf.length,InetAddress.getByName("code-geass"),8000);
ds.send(dp);
}
ds.close();
}
}
键盘录入接收端:
定义Socket服务。
while(true){
不断接受发送端传来的数据。因为receive是阻塞式方法。所以不会无限循环。
}
import java.net.*;
class UDPRece
{
public static void main(String[] args) throws Exception
{
DatagramSocket ds = new DatagramSocket(8000);
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);
}
//ds.close();
}
}
编写聊天程序:
因为接受和发送要同时进行,所以要用多线程。
TCP
Socket和ServerSocket
建立客户端和服务端。
建立连接后,通过Socket中的IO流进行数据传输。
关闭资源。
步骤:
客户端:
1,创建Socket服务,并且指定需要连接的主机和端口。
服务端:
1,建立服务端的socket服务。ServerSocket();
2,获取连接过来的客户端对象。通过accept方法。没有连接就等。阻塞式。
3,客户端如果发来数据,那么服务端要使用对象的客户端对象。并获取到该客户端对象的读取流来读取发送过来的数据。
4,关闭资源(可选)。
客户端和服务端的互访:
客户端:
1.建立socket服务。指定要连接主机和端口。
2。获取socket流中的输出流。将数据写到该流中。并通过网络发送给服务端。
3,获取socket流中的输入流,将服务端的反馈的数据获取。
4,关闭客户端资源。
import java.net.*;
import java.io.*;
class TCPClient
{
public static void main(String[] args) throws Exception
{
Socket s = new Socket(InetAddress.getByName("192.168.1.211"),30000);
BufferedReader br = new BufferedReader(new InputStreamReader(System.in));
OutputStream os = s.getOutputStream();
String line=null;
InputStream is = s.getInputStream();
byte[] buf = new byte[1024];
int len = 0;
while((line=br.readLine())!=null)
{
if(line.equals("over"))
break;
os.write(line.getBytes());
/*String ip = s.getInetAddress().getHostAddress();
System.out.println(ip);*/
len=is.read(buf);
System.out.println("sever:"+new String(buf,0,len));
}
s.close();
}
}
class TCPServer
{
public static void main(String[] args)throws Exception
{
ServerSocket ss = new ServerSocket(30000);
Socket s = ss.accept();
//String ip = ss.toString();
InputStream is = s.getInputStream();
OutputStream os =s.getOutputStream();
byte[] buf =new byte[1024];
int len=0;
while((len=is.read(buf))!=-1)
{
String str = new String(buf,0,len).toUpperCase();
os.write(str.getBytes());
}
s.close();
ss.close();
}
}
客户端上传文件到服务端注意:
因为服务端无法识别客户端的数据是否传送完毕,所以在客户端数据传输 完毕后需要在后面加上shutdownOutput();视为结尾标记。
客户端并发上传数据:
定义多线程,明确客户端要在服务端所执行的代码。
import java.net.*;
import java.io.*;
class ThreadDemo implements Runnable
{
private Socket s;
ThreadDemo(Socket s)
{
this.s=s;
}
public void run()
{
int count=1;
try
{
InputStream in = s.getInputStream();
File file = new File("copy.gif");
while(file.exists())
file=new File("copy("+(count++)+").gif");
FileOutputStream fos = new FileOutputStream(file);
PrintWriter pw = new PrintWriter(s.getOutputStream(),true);
byte[] buf=new byte[1024];
int len = 0;
while((len=in.read(buf))!=-1)
{
fos.write(buf,0,len);
}
pw.println("OK");
s.close();
fos.close();
}
catch (IOException e)
{
throw new RuntimeException("error");
}
}
}
class PicClient
{
public static void main(String[] args) throws Exception
{
Socket s = new Socket("code-geass",5000);
FileInputStream fis = new FileInputStream("460.gif");
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();
BufferedReader br = new BufferedReader(new InputStreamReader(s.getInputStream()));
String str=br.readLine();
System.out.println(str);
s.close();
br.close();
}
}
class PicServer
{
public static void main(String[] args) throws Exception
{
ServerSocket ss = new ServerSocket(5000);
while(true)
{
Socket s = ss.accept();
new Thread(new ThreadDemo(s)).start();
}
//ss.close();
}
}
URL:可对web地址进行字符串截取。
SocketAddress和InetAddress
前者是IP地址+端口。后者只是IP。
ServerSocket构造函数中backlog参数表示最大连接数。