一,什么是Socket
网络上的两个程序通过一个双向的通信连接实现数据交换,这个连接的一端称为一个socket
Socket两种通信模型
-UDP
-TCP 持续性输送消息
HTTP和Socket的区别
HTTP是应用层
Socket是传输层
1.实现简易聊天室(UDP)
a.UDP服务端创建
public class UdpServer {
//可以确定到指定的机器
private InetAddress mInetAddress;
//声明端口号 确定具体的应用程序 尽量用5000以后的 避免被占用
private int mPort = 7777;
//UDP相关的类
private DatagramSocket mSocket;
//控制台输入类
private Scanner scanner;
public UdpServer() {
try {
//本机地址
mInetAddress = InetAddress.getLocalHost();
//初始化 Socket
mSocket = new DatagramSocket(mPort,mInetAddress);
//在控制台输入
scanner = new Scanner(System.in);
//换行
scanner.useDelimiter("\n");
} catch (UnknownHostException e) {
e.printStackTrace();
} catch (SocketException e) {
e.printStackTrace();
}
}
public void start(){
while (true){
try {
byte[] buf = new byte[1024];
//接收一个数据包
DatagramPacket received = new DatagramPacket(buf,buf.length);
//socket接收数据包
mSocket.receive(received);
//获取客户端的地址
InetAddress address = received.getAddress();
//获取客户端端口号
int pot = received.getPort();
//获取客户端发送的什么信息 返回来的是一个byte数组可以解析为一个String
// byte[] data = received.getData();
//参数1byte数组 参数2从0开始 参数3 长度
String clientMsg = new String(received.getData(),0,received.getLength());
System.out.println("address : " + address + "pot : " + "clientMsg : " + clientMsg);
//获取输入台给客户端返回的数据
String returnMsg = scanner.next();
//把获取的String类型的数据转化为byte
byte[] returnMsgbytes = returnMsg.getBytes();
//把输入的内容发送给客户端 参数1 内容 参数2长度 参数3 客户端端口信息地址
DatagramPacket sendPacket = new DatagramPacket(returnMsgbytes,returnMsgbytes.length,received.getSocketAddress());
//发送包
mSocket.send(sendPacket);
} catch (IOException e) {
e.printStackTrace();
}
}
}
public static void main(String [] args){
new UdpServer().start();
}
}
b.客户端
public class UdpclientBiz {
//指定服务器IP 本机IP
private String mServeIP="192.168.0.103";
//可以确定到指定的机器
private InetAddress mInetAddress;
//声明端口号 确定具体的应用程序 尽量用5000以后的 避免被占用
private int mPort = 7777;
//UDP相关的类
private DatagramSocket mSocket;
//控制台输入类
private Scanner scanner;
private Handler handler = new Handler(Looper.myLooper());
public UdpclientBiz() {
try {
//本机地址
mInetAddress = InetAddress.getByName(mServeIP);
//初始化 Socket创建默认 会随机一个端口号
mSocket = new DatagramSocket();
//在控制台输入
scanner = new Scanner(System.in);
//换行
scanner.useDelimiter("\n");
} catch (UnknownHostException e) {
e.printStackTrace();
} catch (SocketException e) {
e.printStackTrace();
}catch (Exception e){
e.printStackTrace();
}
}
public interface OnMsgReturnedListener{
void onMsgReturned(String msg);
void onError(Exception e);
}
//发送完成后接收服务端的信息
public void sendMsg(final String msg, final OnMsgReturnedListener onMsgReturnedListener){
new Thread(){
@Override
public void run() {
try {
//发送到服务端的数据
//获取控制台输入的内容
String clientMsg = scanner.next();
//转化成byte
byte[] clientMsgBytes = msg.getBytes();
//打包 参数1 byte 参数2 长度 参数3地址 参数4 端口号
DatagramPacket datagramPacket = new DatagramPacket(clientMsgBytes,clientMsgBytes.length,mInetAddress,mPort);
mSocket.send(datagramPacket);
//接收到服务端的数据
byte[] buf = new byte[1024];
//打包
DatagramPacket datagramPacket1 = new DatagramPacket(buf,buf.length);
final String serverMsg = new String(datagramPacket1.getData(),0,datagramPacket1.getLength());
//发送
mSocket.receive(datagramPacket1);
handler.post(new Runnable() {
@Override
public void run() {
onMsgReturnedListener.onMsgReturned(serverMsg);
}
});
} catch (final IOException e) {
handler.post(new Runnable() {
@Override
public void run() {
onMsgReturnedListener.onError(e);
}
});
}
}
}.start();
//发送数据
}
public void start(){
while (true){
try {
//发送到服务端的数据
//获取控制台输入的内容
String clientMsg = scanner.next();
//转化成byte
byte[] clientMsgBytes = clientMsg.getBytes();
//打包 参数1 byte 参数2 长度 参数3地址 参数4 端口号
DatagramPacket datagramPacket = new DatagramPacket(clientMsgBytes,clientMsgBytes.length,mInetAddress,mPort);
//发送数据
mSocket.send(datagramPacket);
//接收到服务端的数据
byte[] buf = new byte[1024];
//打包
DatagramPacket datagramPacket1 = new DatagramPacket(buf,buf.length);
//发送
mSocket.receive(datagramPacket1);
// byte[] buf = new byte[1024];
// //接收一个数据包
// DatagramPacket received = new DatagramPacket(buf,buf.length);
// //socket接收数据包
// mSocket.receive(received);
// //获取客户端的地址
// InetAddress address = received.getAddress();
// //获取客户端端口号
// int pot = received.getPort();
// //获取客户端发送的什么信息 返回来的是一个byte数组可以解析为一个String
// // byte[] data = received.getData();
// //参数1byte数组 参数2从0开始 参数3 长度
// String clientMsg = new String(received.getData(),0,received.getLength());
//
// System.out.println("address : " + address + "pot : " + "clientMsg : " + clientMsg);
//
//
// //获取输入台给客户端返回的数据
// String returnMsg = scanner.next();
// //把获取的String类型的数据转化为byte
// byte[] returnMsgbytes = returnMsg.getBytes();
// //把输入的内容发送给客户端 参数1 内容 参数2长度 参数3 客户端端口信息地址
// DatagramPacket sendPacket = new DatagramPacket(returnMsgbytes,returnMsgbytes.length,received.getSocketAddress());
// //发送包
// mSocket.send(sendPacket);
} catch (IOException e) {
e.printStackTrace();
}
}
}
public void onDestroy(){
if(mSocket!= null){
mSocket.close();
}
}
}
c.调用
public class MainActivity extends AppCompatActivity {
private EditText edi;
private Button btn;
private TextView text;
private UdpclientBiz udpclientBiz = new UdpclientBiz();
@Override
protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.activity_main);
edi = findViewById(R.id.edi);
btn = findViewById(R.id.btn);
text = findViewById(R.id.text);
btn.setOnClickListener(new View.OnClickListener() {
@Override
public void onClick(View v) {
String msg = edi.getText().toString();
appendMsg("客户端" + msg);
if(TextUtils.isEmpty(msg)){
}else {
udpclientBiz.sendMsg(msg, new UdpclientBiz.OnMsgReturnedListener() {
@Override
public void onMsgReturned(String msg) {
appendMsg("服务器" + msg);
}
@Override
public void onError(Exception e) {
e.printStackTrace();
}
});
}
}
});
}
private void appendMsg(String msg){
text.append(msg + "\n");
}
}