package socket;
成都创新互联于2013年开始,是专业互联网技术服务公司,拥有项目成都做网站、网站设计网站策划,项目实施与项目整合能力。我们以让每一个梦想脱颖而出为使命,1280元行唐做网站,已为上家服务,为行唐各地企业和个人服务,联系电话:18982081108
import java.io.BufferedReader;
import java.io.IOException;
import java.io.InputStreamReader;
import java.io.PrintWriter;
import java.net.ServerSocket;
import java.net.Socket;
public class SocketService {
//搭建服务器端
public static void main(String[] args) throws IOException{
SocketService socketService = new SocketService();
//1、a)创建一个服务器端Socket,即SocketService
socketService.oneServer();
}
public void oneServer(){
try{
ServerSocket server=null;
try{
server=new ServerSocket(5209);
//b)指定绑定的端口,并监听此端口。
System.out.println("服务器启动成功");
//创建一个ServerSocket在端口5209监听客户请求
}catch(Exception e) {
System.out.println("没有启动监听:"+e);
//出错,打印出错信息
}
Socket socket=null;
try{
socket=server.accept();
//2、调用accept()方法开始监听,等待客户端的连接
//使用accept()阻塞等待客户请求,有客户
//请求到来则产生一个Socket对象,并继续执行
}catch(Exception e) {
System.out.println("Error."+e);
//出错,打印出错信息
}
//3、获取输入流,并读取客户端信息
String line;
BufferedReader in=new BufferedReader(new InputStreamReader(socket.getInputStream()));
//由Socket对象得到输入流,并构造相应的BufferedReader对象
PrintWriter writer=new PrintWriter(socket.getOutputStream());
//由Socket对象得到输出流,并构造PrintWriter对象
BufferedReader br=new BufferedReader(new InputStreamReader(System.in));
//由系统标准输入设备构造BufferedReader对象
System.out.println("Client:"+in.readLine());
//在标准输出上打印从客户端读入的字符串
line=br.readLine();
//从标准输入读入一字符串
//4、获取输出流,响应客户端的请求
while(!line.equals("end")){
//如果该字符串为 "bye",则停止循环
writer.println(line);
//向客户端输出该字符串
writer.flush();
//刷新输出流,使Client马上收到该字符串
System.out.println("Server:"+line);
//在系统标准输出上打印读入的字符串
System.out.println("Client:"+in.readLine());
//从Client读入一字符串,并打印到标准输出上
line=br.readLine();
//从系统标准输入读入一字符串
} //继续循环
//5、关闭资源
writer.close(); //关闭Socket输出流
in.close(); //关闭Socket输入流
socket.close(); //关闭Socket
server.close(); //关闭ServerSocket
}catch(Exception e) {//出错,打印出错信息
System.out.println("Error."+e);
}
}
}
//==============Server.java=================//
import java.io.IOException;
import java.net.ServerSocket;
import java.net.Socket;
public class Server {
public static void main(String[] args) throws IOException {
ServerSocket s = new ServerSocket(12345);
System.out.println("服务器就绪,请启动客户端.");
Socket so = s.accept();
byte[] buff = new byte[1024];
int read = so.getInputStream().read(buff);
String[] abc=new String(buff,0,read).split("\\D+");
int a = Integer.parseInt(abc[0]);
int b = Integer.parseInt(abc[1]);
int c = Integer.parseInt(abc[2]);
if(!cbt(a,b,c))
so.getOutputStream().write("输入的数据无法组成三角形.".getBytes());
else
so.getOutputStream().write(getArea(a,b,c).getBytes());
so.getOutputStream().flush();
so.close();
s.close();
}
private static String getArea(int a, int b, int c) {
float s = (a+b+c)/2f;
return "面积: "+Math.sqrt(s*(s-a)*(s-b)*(s-c));
}
private static boolean cbt(int a, int b, int c) {
return a0b0c0a+bcb+caa+cb;
}
}
//=================Client.java======================//
import java.io.IOException;
import java.net.Socket;
import java.net.UnknownHostException;
public class Client {
public static void main(String[] args) throws UnknownHostException, IOException {
System.out.println("输入三角形的三边并用逗号隔开,如: (3,4,5) ");
byte[] buff=new byte[64];
int r = System.in.read(buff);
String ipaddr = "localhost";//根据情况改变,在本机调试就不改了
Socket so = new Socket(ipaddr,12345);
so.getOutputStream().write(new String(buff,0,r).getBytes());
r = so.getInputStream().read(buff);
so.close();
String rs = new String(buff,0,r);
System.out.println(rs);
}
}
//先启动Server,再启动Client
import java.awt.*;
import javax.swing.*;
import java.awt.event.*;
import java.net.*;
import java.io.*;
public class Client extends JFrame
{
/**
*
*/
private static final long serialVersionUID = -4733717749265129757L;
Container con=null;
JTextArea jta = null;
JTextField jtf = null;
//ArrayList al = new ArrayList();
//ServerSocket ss = null;
Socket s = null;
Client(String ip,int port)
{
try
{
s = new Socket(ip,port); //创建一个流套接字并将其连接到指定 IP 地址的指定端口号。
launchFrame();
}
catch(Exception e)
{
e.printStackTrace();
}
new Thread(new ClientR()).start();
}
public void sent(String str)
{ //发送消息方法
try
{
DataOutputStream dos = new DataOutputStream(s.getOutputStream()); // 创建一个新的数据输出流,将数据写入指定 返回s的套接字的输出流。
dos.writeUTF(str);
}
catch(Exception e)
{
e.printStackTrace();
}
}
public void disconnect() throws Exception
{
s.close(); //失去连接,关闭线程s
}
class ClientR implements Runnable
{//客户端运行
/*Runnable 接口应该由那些打算通过某一线程执行其实例的类来实现。类必须定义一个称为 run 的无参数方法。
设计该接口的目的是为希望在活动时执行代码的对象提供一个公共协议。例如,Thread 类实现了 Runnable。
激活的意思是说某个线程已启动并且尚未停止。
此外,Runnable 为非 Thread 子类的类提供了一种激活方式。
通过实例化某个 Thread 实例并将自身作为运行目标,就可以运行实现 Runnable 的类而无需创建 Thread 的子类。
大多数情况下,如果只想重写 run() 方法,而不重写其他 Thread 方法,那么应使用 Runnable 接口。这很重要,
因为除非程序员打算修改或增强类的基本行为,否则不应为该类创建子类。
*/
public void run()
{
try
{
DataInputStream dis = new DataInputStream(s.getInputStream());//使用指定的底层 s.getInputStream(s的套接字的输入流) 创建一个 DataInputStream(数据输入流)
String str = dis.readUTF();
while(true)
{
jta.append(str+"\n");
str = dis.readUTF();
}
}
catch(Exception e)
{
e.printStackTrace();
}
}
}
public void startClient()
{ //客户端启用
try
{
BufferedReader br = new BufferedReader(new InputStreamReader(System.in)); //读取数据流
String str = br.readLine();
System.out.println(str);
while(true)
{
sent(str); //发送数据
if(str.equals("q"))
{ //如果读取的字符为q
disconnect(); //断开连接
return ;
}
str=br.readLine();
}
}
catch(Exception e)
{
e.printStackTrace();
}
}
public void launchFrame() throws IOException
{ //客户端面板布局
con = this.getContentPane();
jta = new JTextArea();
jtf = new JTextField();
final JTextField jtf1=new JTextField(10);
final JButton jb=new JButton("确认");
Panel p=new Panel();
//Panel p1=new Panel();
JLabel jl=new JLabel();
jl.setText("your name:");
//jl.getVerticalTextPosition();
jtf1.setBackground(Color.PINK);
jtf1.setBounds(10, 10, 10, 10);
p.add(jl);
p.add(jtf1);
p.add(jb);
jb.addActionListener(new ActionListener()
{
public void actionPerformed(ActionEvent e)
{
//e.getWhen();
e.getActionCommand();
jtf.setText(jtf1.getText().toString()+"say:");
}
});
jta.setBackground(Color.LIGHT_GRAY);
jta.setEditable(false); //不可编辑文本域
JScrollPane jsp = new JScrollPane(jta, //jta上滚动条的创建
JScrollPane.VERTICAL_SCROLLBAR_ALWAYS,
JScrollPane.HORIZONTAL_SCROLLBAR_AS_NEEDED);
//con.add(jb,BorderLayout.WEST);
con.add(jsp,BorderLayout.CENTER);
con.add(p,BorderLayout.NORTH);
con.add(jtf,BorderLayout.SOUTH);
jtf.addActionListener(new ActionListener()
{ ///事件监听
public void actionPerformed(ActionEvent e)
{
String str = jtf.getText().toString();
Client.this.sent(str);
jtf.setText(jtf1.getText().toString()+"say:");
}
});
this.setTitle("聊天客户端,袭风版");
this.setBounds(200,200,300,400);
this.setDefaultCloseOperation(EXIT_ON_CLOSE);
this.setBackground(Color.blue);
this.setVisible(true);
}
public static void main (String[] args)
{
System.out.println("===1");
Client cli = new Client("127.168.1.1",3456); //创建一个客户端,并将其连接到指定 IP 地址的指定端口号,其端口号与服务器端一致。与服务器建立连接
System.out.println("===2");
cli.startClient(); //127.0.0.1为本机端口
}
}
//
//import java.net.*;
//import java.io.*;
//
///*
// 发送给服务器端
//*/
//class Send implements Runnable
//{
// private Socket socket;
// Send(Socket socket)
// {
// this.socket = socket;
// }
// public void run()
// {
// try
// {
// BufferedReader bufr =
// new BufferedReader(new InputStreamReader(System.in));
//
// String line = null;
// while((line=bufr.readLine())!=null)
// {
// if("886".equals(line))
// {
// socket.close();
// break;
// }
// byte[] bufString = line.getBytes();
//
// //通过socket对象获取socket流中的输出流对象。
// OutputStream out = socket.getOutputStream();
// out.write(bufString);
//
// InputStream in = socket.getInputStream();
// byte[] buf = new byte[1024];
// int num = in.read(buf);
// String str = new String(buf,0,num);
//
// System.out.println("server:"+str);
// }
//
//
// }
// catch (Exception e)
// {
// System.out.println(e.toString());
// }
// }
//}
//
///*
// 建立服务器
//*/
//class Rece implements Runnable
//{
// //1,建立服务端的socket服务。并监听一个端口。以获取客户端发来的数据。
// private ServerSocket serverSocket;
// Rece(ServerSocket serverSocket)
// {
// this.serverSocket = serverSocket;
// }
// public void run()
// {
// try
// {
// while(true){
// System.out.println("============4");
// Socket socket = serverSocket.accept();
// System.out.println("============5");
// String ip = socket.getInetAddress().getHostAddress();
// System.out.println("============6");
// System.out.println(ip+"...connected");
// System.out.println("============7");
// BufferedReader in = new BufferedReader(new InputStreamReader(socket.getInputStream()));
// System.out.println("============8");
// String line ="";
// System.out.println("============9");
//
// OutputStream out = socket.getOutputStream();
// out.write("开始".getBytes());
//
// while((line= in.readLine())!=null){
// System.out.println(line);
// }
//
// }
// }
// catch (Exception e)
// {
// System.out.println(e.toString());
// }
// }
//}
//
//
//class ChatDemoServer
//{
// public static void main(String[] args) throws Exception
// {
// //1,建立服务端的socket服务。并监听一个端口。以获取客户端发来的数据。
// System.out.println("========1");
// ServerSocket rece = new ServerSocket(8082);
// rece.close();
// System.out.println("========2");
// new Thread(new Rece(rece)).start();
// System.out.println("========3");
// }
//}
//
//
//class ChatClient
//{
// public static void main(String[] args) throws Exception
// {
// //1,建立服务端的socket服务。并监听一个端口。以获取客户端发来的数据。
// //建立客户端socket服务。并去连接指定的服务端。
// Socket send = new Socket("169.254.1.60",10086);
// if(send == null){
// System.out.println("【创建Socket失败!】");
// return;
// }
// new Thread(new Send(send)).start();
// }
//}
import java.net.*;
import java.io.*;
import java.util.*;
//import java.awt.event.*;
import javax.swing.*;
import java.awt.*;
public class Server extends JFrame
{
/**
* 套接字接口可分为三类:公认端口 注册端口 动态和/或私有端口
套接字,简单的说就是通信的两方的一种约定,用套接字中的相关函数来完成通信过程
*/
private static final long serialVersionUID = 4130666237241201704L;
Container con = null; //容器
JTextArea jta = null; //文本区
ServerSocket ss = null; //初始化服务器套接字
ArrayList al = new ArrayList();//ArrayList容器
Server(int port)
{ //构造函数
try
{
ss=new ServerSocket(port); // 创建绑定到特定端口的服务器套接字。
}
catch(Exception e)
{
e.printStackTrace();
}
launchFrame();
}
public void severStart()
{ //线程开始
while(true)
{
try{
Socket s = ss.accept(); //侦听并接受到此套接字(port)的连接。
al.add(new ServerR(s));
jta.append("New Client:"+"\n Ip: "+s.getInetAddress()+":"+s.getPort()+"\n" //得到客户端本地地址,端口和客户端数量
+"Clients count:"+al.size()+"\n");
}
catch(Exception e)
{
e.printStackTrace();
}
}
}
class ServerR implements Runnable
{
Socket s = null; //创建新服务线程
ServerR(Socket s)
{
this.s = s;
new Thread(this).start();//启动新线程
}
public void sent(String str)
{ //发送数据流方法
try
{
DataOutputStream dos = new DataOutputStream(s.getOutputStream()); //从s套接字中读出输出数据流
dos.writeUTF(str); //使用 UTF-8 修改版编码将一个字符串写入基础输出流。
}
catch(Exception e)
{
e.printStackTrace();
}
}
public void run()
{
try
{
DataInputStream dis = new DataInputStream(s.getInputStream());
String str = dis.readUTF(); //读出输入的数据流
while(true)
{
// System.out.println (str);
Iterator ite = al.iterator(); //生成list迭代器
while(ite.hasNext())
{ //如果仍有可迭代的元素,返回true
((ServerR)ite.next()).sent(str); //返回(ServerR)的下一个元素,并发送它
//先遍历ServerR中的所有线程
}
str=dis.readUTF();
}
}
catch(Exception e)
{
try{ //客户端关闭捕捉
s.close(); //关闭一个相关客户端线程
al.remove(this); //从迭代器指向的集合中移除迭代器返回的最后一个元素
jta.append("A client quit!\nClients count:"+al.size()+"\n"); //统计客户端现有的数量
}
catch(Exception e2)
{
e2.printStackTrace();
}
e.printStackTrace();
}
}
}
public void launchFrame()
{ //服务器端面板布局
con = this.getContentPane();
jta = new JTextArea();
jta.setEditable(false); //不可编辑文本域
JScrollPane jsp = new JScrollPane(jta,
JScrollPane.VERTICAL_SCROLLBAR_ALWAYS,
JScrollPane.HORIZONTAL_SCROLLBAR_AS_NEEDED);
con.add(jsp,BorderLayout.CENTER);
this.setTitle("聊天服务端,袭风版");
this.setBounds(200,200,300,400);
this.setDefaultCloseOperation(EXIT_ON_CLOSE);
this.setVisible(true);
}
public static void main (String[] args)
{
Server s = new Server(3456); //创建服务器S 端口为3456
s.severStart();
}
}
区别在于,通讯前
服务器端套接在 在某一端口处监听客户端的连接,等客户端连接
客户端连接服务器端的 ip 和端口,
等双方连接起来的时候 就可以互相通讯,双方没有区别了。
注意:要保证输出与读取用同样的字符集(例子中用的是UTF-8)
//输出包含中文的文本
import java.io.*;
import java.nio.*;
String str="Java套接字如何传输中文";
Socket s=......;
PrintWriter pw=new PrintWriter(new OutputStreamWriter(s.getOutputStream(),Charset.forName("UTF-8")));
pw.println(str);
pw.close();
//读取包含中文的文本
import java.io.*;
import java.nio.*;
String str;
Socket s=......;
BufferedReader br=new BufferedReader(new InputStreamReader(s.getInputStream(),Charset.forName("UTF-8")));
str=br.readLine();
br.close();
将
Socket Socket=ServerSocket.accept();
System.out.println("IP地址"+Socket.getInetAddress()+"端口"+Socket.getPort()+"已经连接到本机");
BufferedReader read = new BufferedReader(new InputStreamReader(Socket.getInputStream(),"UTF-8"));
PrintWriter pw =new PrintWriter(Socket.getOutputStream(),true);
拿到while循环外面,这样服务器端只为第一个连接的客服端服务,程序会正常。或者将Socket=ServerSocket.accept();返回的sock交给宁一个线程处理,然后循环调用String st=read.readLine();读取数据,这样就是一个比较标准的服务器端了,为每一个连进来的客服端,开一个单独的线程为之服务。
主要要理解Socket=ServerSocket.accept();这句代码,返回的Socket是针对单独的一个客户端的,当没有客户端连接时,这句代码会阻塞,直到有客户端连接进来生成的与之对应的客户端。
现在报错是因为,与客户端相对应Socket,读了一行数据,就销毁了,然后又循环到Socket=ServerSocket.accept();去等待一个新的连接。而客户端还往已经销毁的socket发数据,当然客户端会抛Connection reset。