udp事例:
import java.io.BufferedReader;
import java.io.IOException;
import java.io.InputStreamReader;
import java.net.DatagramPacket;
import java.net.DatagramSocket;
import java.net.InetAddress;
import java.net.UnknownHostException;
public class IPDemo {
public static void main(String[] args) throws Exception {
DatagramSocket send =new DatagramSocket(8888);
DatagramSocket rec=new DatagramSocket(8975);
//开启两个线程进行发送和接收
new Thread(new recTask(rec)).start();
new Thread(new sendTask(send)).start();
}
}
class sendTask implements Runnable {
private DatagramSocket ds;
public sendTask(DatagramSocket ds) {
super();
this.ds = ds;
}
@Override
public void run() {
//从键盘读取数据
BufferedReader br = new BufferedReader(new InputStreamReader(System.in));
String line = null;
try {
while ((line = br.readLine()) != null) {
if (line.equals("over")) {
break;
}
//封装数据包,注意端口号,接收端需一致
byte[] buff = line.getBytes();
DatagramPacket dp = new DatagramPacket(buff, buff.length,
InetAddress.getByName("202.195.175.85"), 8975);
//socket发送数据包
ds.send(dp);
}
ds.close();
} catch (IOException e) {
e.printStackTrace();
}
}
}
class recTask implements Runnable {
private DatagramSocket ds;
public recTask(DatagramSocket ds) {
super();
this.ds = ds;
}
@Override
public void run() {
while(true){
try {
//通过字节数组进行接收到内容
byte[] buff =new byte[1024];
DatagramPacket dp =new DatagramPacket(buff, buff.length);
//socket接收数据包
ds.receive(dp);
byte[] data = dp.getData();
//获取主机名
String hostAddress = dp.getAddress().getHostAddress();
String content =new String(data);
if(content.equals("over")){
System.out.println(hostAddress+"离开");
}
System.out.println("ip"+":"+hostAddress+"....."+content);
} catch (IOException e) {
e.printStackTrace();
}
}
}
}
下面是tcp传输图片的例子,首先是客户端
package cn.java.socket;
import java.io.FileInputStream;
import java.io.IOException;
import java.io.OutputStream;
import java.net.Socket;
import java.net.UnknownHostException;
public class TcpSocketClient {
public static void main(String[] args) {
try {
System.out.println("客户端启动!");
Socket scoket =new Socket("202.195.175.85",9800);
//获取socket端的输出流
OutputStream os = scoket.getOutputStream();
//读取本地要发送的文件
FileInputStream fin = new FileInputStream("c:\\1.jpg");
byte[] buff=new byte[1024];
//想服务端写入数据
while(fin.read(buff)!=-1){
os.write(buff, 0, buff.length);
}
//发送完数据定义一个标志告诉服务端已经传输完数据,不然服务端会一直阻塞
scoket.shutdownOutput();
fin.close();
os.close();
} catch (Exception e) {
throw new RuntimeException(e);
}
}
}
下面是服务器端
package cn.java.socket;
import java.io.FileOutputStream;
import java.io.IOException;
import java.io.InputStream;
import java.net.ServerSocket;
import java.net.Socket;
public class TcpSocketServer {
public static void main(String[] args) throws Exception {
//创建服务端socket
ServerSocket ss = new ServerSocket(9800);
while(true){
System.out.println("服务端启动");
//获取客户端socket
Socket cs = ss.accept();
//使用多线程处理多个连接io请求
new Thread(new Task(cs)).start();
}
}
}
class Task implements Runnable{
private Socket cs;
public Task(Socket cs) {
super();
this.cs = cs;
}
@Override
public void run() {
InputStream ins;
try {
ins = cs.getInputStream();
//服务端读取客户端数据写入本地
FileOutputStream fos = new FileOutputStream("e:\\2.jpg");
byte[] buff =new byte[1024];
while(ins.read(buff)!=-1){
fos.write(buff, 0, buff.length);
}
fos.close();
ins.close();
} catch (IOException e) {
e.printStackTrace();
}
}
}
由于使用的是阻塞式的io去读写,在客户端发送完成数据时,要告知服务端io已经没有数据要传送了,使用socket的shutdown关闭输出流。类似于一个标记告知了服务端另外在服务端一直没有关闭socket,所以一直处于监听状态。当有多个线程并发访问
Socket cs = ss.accept(),此时需要开启多个线程去处理,不然客户端就不能处理其他连接过来的socket。