Java TCP通信概念及实例
TCP/UDP 协议
通俗解释:
TCP协议和UDP协议的区别类似于电话系统和邮政系统。
<1>TCP:类似于电话系统,建立双向的通信通道,确定连接,话音顺序接听。
<2>UDP:类似于邮政系统,发送方将信件发送到正确的地址,但并不知道准确的邮路,大多数邮件到达了目的地,个别情况一些邮件会在路上丢失。邮件不保证顺序到达目的地。
TCP套接字
Socket
客户端的通信套接字,可指定远端IP地址、端口进行连接通信,也可以通过方法获取已连接的socket的远端IP地址、端口,以及将此socket以字节输入流和输出流的形式返回,当与数据输入流和输出流绑定,便可实现客户端的网络通信。
构造函数均为public修饰类型,如果创建socket时发生I/O错误,均抛出IOException异常。常用构造函数如下:
Socket(InetAddress address,int port):创建一个socket并与规定的IP地址的指定的端口相连接。
Socket(String host,int port):创建一个socket并与指定主机的指定端口连接。
ServerSocket
服务器的通讯套接字,用来侦听客户端请求的连接,并为每个新连接创建一个socket对象,由此创建绑定此socket的输入流和输出流,与客户端实现网络通信。
构造函数均为public修饰类型,如果创建socket时发生I/O错误,均抛出IOException异常。常用构造函数如下:
ServerSocket(int port):在所给定的用来侦听的端口上建立一个服务器套接字。如果端口号为0,则在任意的空闲的端口上建立要给服务器套接字。外来连接请求的数量默认最大为50。
多线程聊天室实例
服务端Cilent
创建ServerSocket并监听设置的端口,调用accpet()方法,直到找到对应的socket与之连接,创建一个线程为止服务。
Launch the Application 部分为Java Swing的窗口部分。
public class ServerCilent {
private JFrame frmServer;
private JTextField textField;
private JTable table;
private JLabel lblNewLabel;
private JButton btnRefresh;
private JButton btnListenstart;
private SocketManager SocketArr=new SocketManager();
//创建 Server端
void getServer(int port)
{
try {
ServerSocket serverSocket=new ServerSocket(port);
System.out.println("已经开启服务端");
while(true)
{
Socket socket=serverSocket.accept();
new W_Thread(socket).start();
SocketArr.add(socket);
SocketArr.sendClientInfo();
}
} catch (Exception e) {
// TODO: handle exception
e.printStackTrace();
}
}
class W_Thread extends Thread
{
Socket socket=null;
private BufferedReader reader;
private PrintWriter writer;
public W_Thread(Socket socket)
{
this.socket=socket;
}
public void run()
{
try {
reader=new BufferedReader(new InputStreamReader(socket.getInputStream()));
writer=new PrintWriter(socket.getOutputStream(),true);
String msg;
while((msg=reader.readLine())!=null )
{
System.out.println(msg);
SocketArr.SendtoAll(msg);
}
} catch (Exception e) {
// TODO: handle exception
e.printStackTrace();
}
}
}
/**
* Launch the application.
*/
public static void main(String[] args) {
EventQueue.invokeLater(new Runnable() {
public void run() {
try {
ServerCilent window = new ServerCilent();
window.frmServer.setVisible(true);
} catch (Exception e) {
e.printStackTrace();
}
}
});
}
/**
* Create the application.
*/
public ServerCilent() {
initialize();
}
/**
* Initialize the contents of the frame.
*/
private void initialize() {
frmServer = new JFrame();
frmServer.setResizable(false);
frmServer.setTitle("ServerCilent");
frmServer.setBounds(100, 100, 452, 371);
frmServer.setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE);
frmServer.getContentPane().setLayout(null);
JPanel panel = new JPanel();
panel.setBorder(new TitledBorder(null, "DefaultSetting", TitledBorder.LEADING, TitledBorder.TOP, null, null));
panel.setBounds(10, 10, 414, 66);
frmServer.getContentPane().add(panel);
panel.setLayout(null);
JLabel lblPort = new JLabel("Port:");
lblPort.setBounds(10, 25, 54, 15);
panel.add(lblPort);
textField = new JTextField();
textField.setBounds(48, 22, 122, 21);
panel.add(textField);
textField.setColumns(10);
btnListenstart = new JButton("Listen&Start");
btnListenstart.addMouseListener(new MouseAdapter() {
@Override
public void mouseClicked(MouseEvent arg0) {
int port=Integer.parseInt(textField.getText());
ServerCilent serverCilent=new ServerCilent();
serverCilent.getServer(port);
textField.setEditable(false);
btnListenstart.setVisible(false);
}
});
btnListenstart.setBounds(254, 21, 136, 23);
panel.add(btnListenstart);
JLabel label = new JLabel("在线人数:");
label.setBounds(10, 298, 82, 15);
frmServer.getContentPane().add(label);
lblNewLabel = new JLabel(String.valueOf(SocketArr.size()));
lblNewLabel.setBounds(75, 298, 54, 15);
frmServer.getContentPane().add(lblNewLabel);
btnRefresh = new JButton("Refresh");
btnRefresh.setBounds(331, 298, 93, 23);
frmServer.getContentPane().add(btnRefresh);
}
}
多线程客户端Cilent
创建Socket,并获取对应的输入输出流即可。
public class Cilent implements Runnable{
/*Swing*/
private JFrame frmLogincilent;
private JTextField IPAdress;
private JTextField Port;
private JTextField Nickname;
private JTextField Sendinfo;
private JButton Sumbit;
private JTextArea ShowArea;
private JButton Send;
/*Stream*/
private BufferedReader reader;
private PrintWriter writer;
@Override
public void run(){
while(true){
try {
ShowArea.append(reader.readLine()+"\n");
} catch (Exception e) {
// TODO: handle exception
}
}
}
public void Create_Socket(InetAddress ip,int port){
ShowArea.append("正在尝试连接到服务端…… ……"+"\n");
try {
Socket socket=new Socket(ip, port);
ShowArea.append("聊天室已经准备好");
frmLogincilent.setTitle("Ip:"+ip+" Port:"+port+" 已连接在线");
reader=new BufferedReader(new InputStreamReader(socket.getInputStream()));
writer=new PrintWriter(socket.getOutputStream(),true);
new Thread(this).start();
} catch (Exception e) {
// TODO: handle exception
}
}
/**
* Launch the application.
*/
public static void main(String[] args) {
EventQueue.invokeLater(new Runnable() {
public void run() {
try {
Cilent window = new Cilent();
window.frmLogincilent.setVisible(true);
} catch (Exception e) {
e.printStackTrace();
}
}
});
}
/**
* Create the application.
*/
public Cilent() {
initialize();
}
/**
* Initialize the contents of the frame.
*/
private void initialize() {
frmLogincilent = new JFrame();
frmLogincilent.setResizable(false);
frmLogincilent.setTitle("Cilent");
frmLogincilent.setBounds(100, 100, 458, 532);
frmLogincilent.setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE);
frmLogincilent.getContentPane().setLayout(null);
JPanel panel = new JPanel();
panel.setBorder(new TitledBorder(null, "Default Setting", TitledBorder.LEADING, TitledBorder.TOP, null, null));
panel.setBounds(10, 10, 424, 84);
frmLogincilent.getContentPane().add(panel);
panel.setLayout(null);
JLabel lblIpAdress = new JLabel("IP Adress:");
lblIpAdress.setBounds(10, 20, 73, 15);
panel.add(lblIpAdress);
IPAdress = new JTextField();
IPAdress.setBounds(82, 17, 142, 21);
panel.add(IPAdress);
IPAdress.setColumns(10);
JLabel lblProt = new JLabel("Prot:");
lblProt.setBounds(10, 48, 54, 15);
panel.add(lblProt);
Port = new JTextField();
Port.setBounds(82, 45, 66, 21);
panel.add(Port);
Port.setColumns(10);
JLabel lblNickname = new JLabel("NickName:");
lblNickname.setBounds(170, 48, 73, 15);
panel.add(lblNickname);
Nickname = new JTextField();
Nickname.setBounds(238, 45, 176, 21);
panel.add(Nickname);
Nickname.setColumns(10);
Sumbit = new JButton("Lock&Login");
Sumbit.addMouseListener(new MouseAdapter() {
@Override
public void mouseClicked(MouseEvent arg0) {
try {
/*Create Socket*/
String ipString=IPAdress.getText();
int port=Integer.parseInt(Port.getText());
String Name=Nickname.getText();
InetAddress ip=InetAddress.getByName(ipString);
Create_Socket(ip, port);
/*Swing*/
IPAdress.setEditable(false);
Port.setEditable(false);
Nickname.setEditable(false);
Sumbit.setVisible(false);
} catch (Exception e) {
// TODO: handle exception
JOptionPane.showMessageDialog(null, "invalid data");
}
}
});
Sumbit.setBounds(272, 16, 142, 23);
panel.add(Sumbit);
ShowArea = new JTextArea();
ShowArea.setBounds(10, 104, 424, 358);
frmLogincilent.getContentPane().add(ShowArea);
Sendinfo = new JTextField();
Sendinfo.setBounds(10, 472, 330, 21);
frmLogincilent.getContentPane().add(Sendinfo);
Sendinfo.setColumns(10);
Send = new JButton("Send");
Send.addMouseListener(new MouseAdapter() {
@Override
public void mouseClicked(MouseEvent arg0) {
writer.println(Nickname.getText()+":"+Sendinfo.getText());
Sendinfo.setText("");
}
});
Send.setBounds(349, 471, 85, 23);
frmLogincilent.getContentPane().add(Send);
}
}
Socket管理类
继承ArrayList,并添加发送的方法SendtoAll(),以及显示当前连接数目的方法SendCilentInfo()
public class SocketManager extends ArrayList{
synchronized void add(Socket x)
{
super.add(x);
}
synchronized void remove(Socket x)
{
super.remove(x);
}
synchronized void SendtoAll(String str)
{
PrintWriter writer=null;
Socket socket;
for(int i=0;i<size();i++)
{
socket=(Socket)get(i);
try {
writer=new PrintWriter(socket.getOutputStream(),true);
if(writer!=null)
{
writer.println(str);
}
} catch (Exception e) {
// TODO: handle exception
e.printStackTrace();
}
}
}
synchronized void sendClientInfo()
{
String info="当前位于聊天室的人数为"+size();
System.out.println(info);
SendtoAll(info);
}
}
示例效果:
Java TCP通信概念及实例的更多相关文章
- Java TCP通信
1.Socket原理 1)Socket简介 socket通常称作“套接字”,用于描述IP地址和端口号,是一个通信链的句柄.在Internet上的主机一般运行了多个服务软件,同时提供几种服务.每种服务都 ...
- java TCP 通信:服务端与客服端
1.首先先来看下基于TCP协议Socket服务端和客户端的通信模型: Socket通信步骤:(简单分为4步) 1.建立服务端ServerSocket和客户端Socket 2.打开连接到Socket的输 ...
- java TCP通信 socket 套接字 用图片上传轰炸服务器
客户端 package com.swift.jinji; import java.io.FileInputStream; import java.io.IOException; import java ...
- TCP通信服务端及客户端代码
Java TCP通信使用的是Socket(客服端)和ServerSocket(服务端),具体代码如下. server端代码: import java.io.BufferedReader; import ...
- TCP通信的实现代码
TCP通信 概念 传输控制协议(TCP,Transmission Control Protocol)是一种面向连接的.可靠的.基于字节流的传输层通信协议. 从百科定义中就可以看出,TCP通信的基本条件 ...
- 【Java TCP/IP Socket】TCP Socket通信中由read返回值造成的的死锁问题(含代码)(转)
书上示例 在第一章<基本套接字>中,作者给出了一个TCP Socket通信的例子——反馈服务器,即服务器端直接把从客户端接收到的数据原原本本地反馈回去. 书上客户端代码如下: 1 2 3 ...
- 【Java TCP/IP Socket】基于NIO的TCP通信(含代码)
NIO主要原理及使用 NIO采取通道(Channel)和缓冲区(Buffer)来传输和保存数据,它是非阻塞式的I/O,即在等待连接.读写数据(这些都是在一线程以客户端的程序中会阻塞线程的操作)的时候, ...
- java 网络编程之TCP通信和简单的文件上传功能
*/ .hljs { display: block; overflow-x: auto; padding: 0.5em; color: #333; background: #f8f8f8; } .hl ...
- TCP通信实现对接硬件发送与接收十六进制数据 & int与byte的转换原理 & java中正负数的表示
今天收到的一份需求任务是对接硬件,TCP通信,并给出通信端口与数据包格式,如下: 1.首先编写了一个简单的十六进制转byte[]数组与byte[]转换16进制字符串的两个方法,如下: /** * 将十 ...
随机推荐
- js将数字转换成中文
var _change = { ary0:["零", "一", "二", "三", ...
- JS浏览器的三种弹框:
1.alert:使用alert弹框提示信息,最后都会被转化为字符串输出(因为调用了toString这个方法).比如alert(1+1)弹出的结果应该是字符串形式的“2”. 2.Confirm:在ale ...
- substring和substr小结
substring 1 substring 方法用于提取字符串中介于两个指定下标之间的字符 2 substring(start,end) 开始和结束的位置,从零开始的索引 end:字符串下标,结束符是 ...
- 【思维题 细节】loj#6042. 「雅礼集训 2017 Day7」跳蚤王国的宰相
挂于±1的细节…… 题目描述 跳蚤王国爆发了一场动乱,国王在镇压动乱的同时,需要在跳蚤国地方钦定一个人来做宰相. 由于当时形势的复杂性,很多跳蚤都并不想去做一个傀儡宰相,带着宰相的帽子,最后还冒着被打 ...
- C/C++程序基础 (十一)标准模板库
标准模板库 标准模板库在标准函数库的定位 迭代器(类似指针)保证算法(常用算法)和容器(数据结构)的结合. vector的实现 底层实现是动态数组,所以支持随机访问. 内部是动态数组,随着insert ...
- Python面向对象--高级(二)
## 使用__slots__限制类的属性 - 之前说到,可以通过在类外部实例或者类名任意定义实例属性或者类属性或者方法 class Person(object): pass Person.name = ...
- php-5.6.26源代码 - PHP文件汇编成opcode、执行
文件 php-5.6.26/Zend/zend.c ZEND_API int zend_execute_scripts(int type TSRMLS_DC, zval **retval, int f ...
- nginx+php整合(是让nginx可以运行php,以及下载地址)
下载地址: nginx:http://nginx.org/en/download.html PHP: https://windows.php.net/download/ 都是官网的自己选择版本 安装文 ...
- static作用域
当一个函数完成时,它的所有变量通常都会被删除.然而,有时候您希望某个局部变量不要被删除. 要做到这一点,请在您第一次声明变量时使用 static 关键字: <?php function myTe ...
- MySQL触发器和更新操作
一.触发器概念 触发器(trigger):监视某种情况,并触发某种操作,它是提供给程序员和数据分析员来保证数据完整性的一种方法,它是与表事件相关的特殊的存储过程,它的执行不是由程序调用,也不是手工启动 ...