您的位置:首页 > 理论基础 > 计算机网络

网络编程概念。一个UDP构造的聊天室

2017-09-19 16:21 375 查看
网络编程:利用网络将不同计算机数据进行交换

网络三要素:

IP地址   +   端口 =Socket

协议 :UDP,TCP     

inetAddress类的使用public class InetAddressDemo {

public static void main(String[] args) throws Exception {
// TODO Auto-generated method stub
InetAddress address = InetAddress.getByName("");
System.out.println(address.getHostAddress());
System.out.println(address.getHostName());
InetAddress localHost = InetAddress.getLocalHost();
System.out.println(localHost);
}

}
用本机名和本机地址

UDP和TCP协议

UDP:将数据源和目的封装在数据包中,不需要建立连接,每个数据包大小在64K内,无连接,是不可靠协议,但是速度很快。

TCP:建立连接,形成传输数据的通道,在连接中进行大数据量的传输;通过三次握手完成连接,是可靠协议,但是效率会稍低。

Socket:应用层和传输层之间的桥梁。下面的底层已经封装好了,我们只需要用Socket进行操作就行了。

Socket原理机制:

通信的两端都有Socket

网络通信其实就是Socket间的通信

数据在两个Socket之间通过IO传输

UDP传输服务器端编写public class Server {

public static void main(String[] args) throws Exception {
// 创建一个服务端Socket并监听指定端口
DatagramSocket ds = new DatagramSocket(8888);
// 接收数据,并将数据放在数据包中
byte[] buf =new byte[64*1024];
int length = buf.length;
DatagramPacket p = new DatagramPacket(buf, length);
ds.receive(p);
// 将包中的数据取出来
byte[] data=p.getData();//获取的是接受到的数据
InetAddress address = p.getAddress();//接受发送过来的主机地址
int port = p.getPort();//获取端口号
String ip = address.getHostAddress();//获取的是客户端的ip地址
int dataLength = p.getLength();
// 将数据转换成字符串
String result = new String(data,0,dataLength);
System.out.println("ip="+ip+",port="+port+",result="+result);
// 关闭资源
ds.close();
}

}

UDP客户端客户端编写public class Client {

public static void main(String[] args) throws Exception {
DatagramSocket ds = new DatagramSocket();
byte[] buf = "UDP发送消息".getBytes();//包数据
int length=buf.length;//包长度
InetAddress address=InetAddress.getByName("127.0.0.1");//目的地址
int port=8888;//目的端口号
DatagramPacket p=new DatagramPacket(buf, length, address, port);
// 调用Socket的发送方法
ds.send(p);
ds.close();
}

}

l聊天室初级版客户端public class Client {

public static void main(String[] args) throws Exception {
DatagramSocket ds = new DatagramSocket();
InetAddress address = InetAddress.getByName("127.0.0.1");
Scanner sc = new Scanner(System.in);
String line;
while (!(line = sc.nextLine()).equals("886")) {
byte[] buf = line.getBytes();
DatagramPacket packet = new DatagramPacket(buf, buf.length, address, 8888);
ds.send(packet);
}
ds.close();
}
}
服务器端
public class Server {

public static void main(String[] args) throws Exception {
DatagramSocket socket = new DatagramSocket(8888);
//		循环接受客户端发送的内容
byte[] buf=new byte[64*1024];
while(true){
DatagramPacket packet = new DatagramPacket(buf, buf.length);
//接受客户端数据并存储到包中
socket.receive(packet);
//			从数据包中取出内容
byte[] data = packet.getData();
int length = packet.getLength();
String ip = packet.getAddress().getHostAddress();
//			将字节数组的形式内容转化成字符串
String result = new String(data,0,length);
System.out.println("ip="+ip+",result="+result);
}
}

}

注意点:服务器端创建Socket直接带端口号

如何和在一个界面上?

运用线程。让这俩个程序运行在同一个主线程内。


此时会报错。Command+option+z,try...catch一下。第一个意思是分别catch,第二个是 catch所有的Exception。

一个完整的UDP聊天室

客户端public class ClientRunnable implements Runnable {

private String ip;
private int port;

public ClientRunnable(String ip, int port) {
this.ip = ip;
this.port = port;
}

@Override
public void run() {
DatagramSocket ds = null;
try {
ds = new DatagramSocket();
InetAddress address = InetAddress.getByName(ip);
Scanner sc = new Scanner(System.in);
String line;
while (!(line = sc.nextLine()).equals("886")) {
byte[] buf = line.getBytes();
DatagramPacket packet = new DatagramPacket(buf, buf.length, address, port);
ds.send(packet);
}
} catch (IOException e) {
// TODO Auto-generated catch block
e.printStackTrace();
} finally {
if (ds != null) {
ds.close();
}
}
}
}
服务器端
public class ServerRunnable implements Runnable {

private int port;

public ServerRunnable(int port) {
this.port = port;
}

@Override
public void run() {
try {
DatagramSocket socket = new DatagramSocket(port);
//		循环接受客户端发送的内容
byte[] buf=new byte[64*1024];
while(true){
DatagramPacket packet = new DatagramPacket(buf, buf.length);
//接受客户端数据并存储到包中
socket.receive(packet);
//			从数据包中取出内容
byte[] data = packet.getData();
int length = packet.getLength();
String ip = packet.getAddress().getHostAddress();
//			将字节数组的形式内容转化成字符串
String result = new String(data,0,length);
System.out.println("ip="+ip+",result="+result);
}
} catch (IOException e) {
// TODO Auto-generated catch block
e.printStackTrace();
}
}

}
主程序
public class ChatRoom {

public static void main(String[] args) {
//		先启动服务端聊天线程,再启动客户端聊天线程
ClientRunnable clientRunnable = new ClientRunnable("127.0.0.1",8888);
ThreadPoolUtils.execute(clientRunnable);
ServerRunnable serverRunnable = new ServerRunnable(8888);
ThreadPoolUtils.execute(serverRunnable);
}

}
线程池
public class ThreadPoolUtils {
private static ExecutorService threadpool = Executors.newCachedThreadPool();

public static void execute(Runnable command) {
threadpool.execute(command);
}
}
内容来自用户分享和网络整理,不保证内容的准确性,如有侵权内容,可联系管理员处理 点击这里给我发消息
标签: