TCP & UDP 编程 在线聊天实现
TCP编程
TCP UDP
TCP编程 :Server Socket Socket
端口:两个字节 0-1024系统保留
ServerSocket 服务器端
ServerSocket ss=new ServerSocket(8888);
syso("服务器已启动");
Socket s=ss.accept();//等待客户端的连接 阻塞 连接之后就不阻塞
InputStream is=s.getInputStream(); //读客户端数据
OutputStream os=s.getOutputStream();//对客户端写数据
PrintStream ps=new PrintStream(s.getOutputStream());
BufferedReader bri=new BufferedReader(new InputStreamReader(s.getInputStream()));
//不断的接收客户端发来的信息 多线程
new Thread(new Runnable(){
public void run()
{
String tem=null;
while(null!=(tem=bri.readline()))
{
syso(">>>>:"+tem);
}
}
}
).start();
//服务器接收键盘的输入,有数据就写到客户端
String str=null;
BufferedReader br=new BufferedReader(new InputStreamReader(System.in));
while (null!=(str=br.readline()))
{
ps.println("server:"+str);
}
netstat -nao |find "8888"
客户端代码
InetAddress ip=InetAddress.getByName("192.168.2.122");
Socket s=new Socket(ip,8888);
InputStream is=s.getInputStream(); //读服务端数据
OutputStream os=s.getOutputStream();//对服务端写数据
new Thread(new Runnable(){
public void run()
{
String tem=null;
while(null!=(tem=bri.readline()))
{
syso("<<<<:"+tem);
}
}
}
).start();
//服务器接收键盘的输入,有数据就写到客户端
String str=null;
BufferedReader br=new BufferedReader(new InputStreamReader(System.in));
while (null!=(str=br.readline()))
{
ps.println("client:"+str);
}
13mmin
PrintWriter 默认不是自动刷新 手动flush 或是 在第二个参数填true
多对多的聊天程序
逻辑:
服务器:
循环接收客户端socket.accept()
连接上先读取一行作为用户名
每次接收后把 socket的输出流和用户名存为HashMap<String,PrintStream>
每次接收到信息,将信息广播到所有客户端
客户端:
先键盘读取输出一句话作为用户名
不断读取键盘输入,写给输出流发送到服务器
不断获取客户端传来的数据,syso()
自定义协议 :协议头,协议体 第三方
UDP:
DatagramPacket
DatagramSocket
receive send DatagramPacket
SocketAddress 封装了客户端的ip
服务器和客户端
package com.udp;
import java.net.DatagramPacket;
import java.net.DatagramSocket;
import java.net.InetAddress;
import java.net.SocketException;
import java.net.UnknownHostException;
public class Server {
public static void main(String[] args) throws Exception {
int port=8888;
InetAddress ipAddress=InetAddress.getByName("10.8.98.139");
DatagramSocket ds=new DatagramSocket(port,ipAddress);//不会阻塞
System.out.println("服务器已启动");
byte [] buffer=new byte[1024];
//用于收数据
DatagramPacket dp=new DatagramPacket(buffer, buffer.length);
ds.receive(dp);//阻塞 ,等待客户端发数据
byte [] redata=dp.getData();
System.out.println("---------------"+new String (redata,0,dp.getLength())+dp.getSocketAddress());//客户端要主动给客户端发个消息
//让服务器知道 客户端的地址
}
}
客户端:
package com.udp;
import java.net.DatagramPacket;
import java.net.DatagramSocket;
import java.net.InetAddress;
public class Client {
public static void main(String[] args)throws Exception {
byte [] data="hello server".getBytes();
DatagramSocket ds=new DatagramSocket();
int port =8888;
InetAddress ip=InetAddress.getByName("10.8.98.139");
DatagramPacket dp=new DatagramPacket(data, data.length, ip,port);
ds.send(dp);//发送数据
}
}
实现聊天 :服务器
package com.udp2;
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.SocketAddress;
public class Server {
int port=8888;
InetAddress ip=null;
DatagramSocket ds=null;
DatagramPacket send=null;
DatagramPacket recieve=null;
SocketAddress sa=null;
byte [] buffer=new byte[1024];
public Server()
{
try {
ip=InetAddress.getByName("10.8.98.139");
ds=new DatagramSocket(port);
send=null;
recieve=new DatagramPacket(buffer, buffer.length);
ds.receive(recieve);//先收一个数据包,以获取对方的IP
sa=recieve.getSocketAddress();
//不断的读客户发来的数据,收到后显示
new ReadClient().start();
//不断的读键盘,并发出去
new ReadKeyBord().start();
}
catch (Exception e) {
// TODO Auto-generated catch block
e.printStackTrace();
}
}
class ReadKeyBord extends Thread{
@Override
public void run() {
String str=null;
BufferedReader br=new BufferedReader(new InputStreamReader(System.in));
try {
while (null!=(str=br.readLine()))
{
byte[] data=str.getBytes();
send=new DatagramPacket(data, data.length,sa);
ds.send(send);
}
} catch (IOException e) {
// TODO Auto-generated catch block
e.printStackTrace();
}
}
}
class ReadClient extends Thread
{
@Override
public void run() {
while (true)
{
try {
ds.receive(recieve);
byte[] data=recieve.getData();
System.out.println("客户端说:"+new String(data,0,recieve.getLength()));
} catch (IOException e) {
// TODO Auto-generated catch block
e.printStackTrace();
}//阻塞
}
}
}
public static void main(String[] args) {
System.out.println("服务器已启动");
new Server();
}
}
客户端:
package com.udp2;
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.SocketAddress;
public class Client {
int port=8888;
InetAddress ip=null;
DatagramSocket ds=null;
DatagramPacket send=null;
DatagramPacket recieve=null;
byte [] buffer=new byte[1024];
public Client()
{
try {
byte[] da="first".getBytes();
ip=InetAddress.getByName("10.8.98.139");
ds=new DatagramSocket();
send=new DatagramPacket(da, da.length,ip,port);
recieve=new DatagramPacket(buffer, buffer.length);
ds.send(send);
//不断的读客户发来的数据,收到后显示
new ReadServer().start();
//不断的读键盘,并发出去
new ReadKeyBord().start();
}
catch (Exception e) {
// TODO Auto-generated catch block
e.printStackTrace();
}
}
class ReadKeyBord extends Thread{
@Override
public void run() {
String str=null;
BufferedReader br=new BufferedReader(new InputStreamReader(System.in));
try {
while (null!=(str=br.readLine()))
{
byte[] data=str.getBytes();
send=new DatagramPacket(data, data.length,ip,port);
ds.send(send);
}
} catch (IOException e) {
// TODO Auto-generated catch block
e.printStackTrace();
}
}
}
class ReadServer extends Thread
{
@Override
public void run() {
while (true)
{
try {
ds.receive(recieve);
byte[] data=recieve.getData();
System.out.println("服务器说:"+new String(data,0,recieve.getLength()));
} catch (IOException e) {
// TODO Auto-generated catch block
e.printStackTrace();
}//阻塞
}
}
}
public static void main(String[] args) {
new Client();
}
}
InetAddress.getByName("10.152.1.49");
recieve.getData();
String 的构造方法: new (byte[] bytes,int offset,int length)