通信基础——实现服务器与客户端的交流
大家好~~~好久不见~~~感谢大家一直以来对我的博客的关注与支持,最近比较忙~~技术博客写得少少的~~对不起一直关注我的朋友们~~现在~~我要写新东西啦~
是不是很期待呢,好的~~下面我将对我在通信方面的成果做一个展示:
服务器端:
下面是做服务器端的一点心得体会:
一、制作服务器端的三大步骤:
1、 在指定端口上创建一个java.net.ServerSocket对象;
2、 当服务器创建成功后,就像的的手机开机后,进入待机状态一样,你也要让服务器进入等待状态,当然是其他客户机来连接它;
3、 从Socket连结对象上调用方法得到输入输出流;
4、 如果你使用过输入/输出流对象,也许不用看这步了;但我还是要提醒下,现在就可以通
信了:从输入流中读取数据,向输出流中写入数据,读到的,即是客户机发来的;
二、避免阻塞现象产生的方法是使用线程,使用线程在每次创建一个连接的时候,不然如果服务器不接收到消息就不会进入下一步,一直阻塞在那里;如果使用界面,建立连接时也需要使用线程;
三、在读取客户端发来的文本信息时,readline()读取中文不会出现乱码,如果按本文中的方法一个字节一个字节地读写就会出现乱码,因为中文占两个字节,不过不推荐使用readline,因为它只能读取文本格式的。
package Connect;
publicclass Connect2 {
/**
*@paramargs
*/
publicstaticvoid main(String[] args) throws Exception {
// TODO Auto-generated method stub
Serverjframe serverjframe = new Serverjframe();
serverjframe.Serverjfr();
}
}
package Connect;
import java.awt.event.ActionEvent;
import java.awt.event.ActionListener;
import javax.swing.JButton;
import javax.swing.JTextArea;
import javax.swing.JTextField;
public class JButtonListener implements ActionListener {
private JTextArea jTextArea;
private String str;
private JTextField jTextField;
private JButton jButton;
private JTextField jTextFieldmsg;
public JButtonListener(JTextField jTextField,JTextArea jTextArea,JButton jButton,JTextField jTextFieldmsg){
this.jTextField = jTextField;
this.jTextArea = jTextArea;
this.jButton = jButton;
this.jTextFieldmsg = jTextFieldmsg;
}
@Override
public void actionPerformed(ActionEvent e) {
// TODO Auto-generated method stub
str = jTextField.getText();
int Str = Integer.parseInt(str);
System.out.println(str);
JframeThread jfThread = new JframeThread(Str,jTextArea,jButton,jTextFieldmsg);
jfThread.start();
}
}
package Connect;
import javax.swing.JButton;
import javax.swing.JTextArea;
import javax.swing.JTextField;
publicclass JframeThread extends Thread{
private JButton jButton;
private JTextField jTextFieldmsg;
private JTextArea jTextArea;
privateintStr;
public JframeThread(int Str,JTextArea jTextArea,JButton jButton,JTextField jTextFieldmsg) {
// TODO Auto-generated constructor stub
this.Str = Str;
this.jTextArea = jTextArea;
this.jTextFieldmsg = jTextFieldmsg;
this.jButton = jButton;
}
publicvoid run(){
Netconnect netconnect = new Netconnect(jTextArea,jButton,jTextFieldmsg);
netconnect.setUpServer(Str);
}
}
package Connect;
import java.awt.event.ActionEvent;
import java.awt.event.ActionListener;
import javax.swing.JTextArea;
import javax.swing.JTextField;
public class JbuttonmsgListener implements ActionListener{
private ServerThread serverThread;
private JTextField jTextField;
private JTextArea jTextArea;
public JbuttonmsgListener(JTextField jTextField,JTextArea jTextArea,ServerThread serverThread){
this.jTextField = jTextField;
this.jTextArea = jTextArea;
this.serverThread = serverThread;
}
@Override
public void actionPerformed(ActionEvent e) {
// TODO Auto-generated method stub
try {
String string ="服务器说:"+jTextField.getText()+"\r\n";
serverThread.sendMsg2Me(string);
jTextArea.append(jTextField.getText());
} catch (Exception e1) {
// TODO Auto-generated catch block
e1.printStackTrace();
}
}
}
package Connect;
import java.io.IOException;
import java.io.InputStream;
import java.io.OutputStream;
import java.net.ServerSocket;
import java.net.Socket;
import java.util.Random;
import javax.swing.JButton;
import javax.swing.JTextArea;
import javax.swing.JTextField;
public class Netconnect {
private JTextArea jTextArea;
private JButton jButton;
private JTextField jTextFieldmsg;
public Netconnect(JTextArea jTextArea,JButton jButton,JTextField jTextFieldmsg){
this.jTextArea = jTextArea;
this.jButton = jButton;
this.jTextFieldmsg = jTextFieldmsg;
}
public void setUpServer(int port) {
try {
ServerSocket server=new ServerSocket(port);
System.out.println("服务器创建成功!"+port);
while(true)
{
Socket client = server.accept();
System.out.println("已经启动一个线程,去处理它呵呵");
ClientAlreadyConnect pClient = new ClientAlreadyConnect();
pClient = pClient.createOne();
System.out.println("用户:"+pClient.getName()+"已经被创建;");
ServerThread st = new ServerThread(client,jTextArea,jButton,jTextFieldmsg,pClient);
st.start();
}
} catch (IOException e) {
// TODO Auto-generated catch block
e.printStackTrace();
}
}
}
package Connect;
import java.awt.BorderLayout;
import java.awt.Dimension;
import javax.swing.JButton;
import javax.swing.JLabel;
import javax.swing.JPanel;
import javax.swing.JTextArea;
import javax.swing.JTextField;
public class Serverjframe extends javax.swing.JFrame {
public void Serverjfr(){
this.setSize(400, 400);
this.setTitle("呵呵服务器");
this.setDefaultCloseOperation(3);
this.setLocationRelativeTo(null);
this.setLayout(new BorderLayout());
//北部创建服务器
JButton jButton = new JButton("端口号:");
JTextField jTextField = new JTextField("8090");
jTextField.setPreferredSize(new Dimension(100,30));
JPanel northjPanel = new JPanel();
northjPanel.add(jButton);
northjPanel.add(jTextField);
this.add(northjPanel,BorderLayout.NORTH);
//中部输入框:
JPanel jPanel = new JPanel();//面板
JButton jButtonmsg = new JButton("发布消息");
JTextField jTextFieldcenter = new JTextField();
jTextFieldcenter.setPreferredSize(new Dimension(280,30));
jTextFieldcenter.setHorizontalAlignment(JTextField.LEFT);
jPanel.add(jButtonmsg);
jPanel.add(jTextFieldcenter);
this.add(jPanel,BorderLayout.CENTER);
//南部显示框
JPanel southjPanel = new JPanel();
JTextArea jTextAreasouth = new JTextArea("");
jTextAreasouth.setPreferredSize(new Dimension(350,260));
southjPanel.add(jTextAreasouth);
this.add(southjPanel,BorderLayout.SOUTH);
this.setVisible(true);
JButtonListener jButtonListener = new JButtonListener(jTextField,jTextAreasouth,jButtonmsg,jTextFieldcenter);
jButton.addActionListener(jButtonListener);
}
}
package Connect;
import java.io.DataInputStream;
import java.io.InputStream;
import java.io.OutputStream;
import java.net.ServerSocket;
import java.net.Socket;
import java.util.Random;
import javax.swing.JButton;
import javax.swing.JTextArea;
import javax.swing.JTextField;
public class ServerThread extends Thread{
private Socket client;//线程对象要处理的连结变量
private OutputStream out;
private JTextArea jTextArea;
private JButton jButton;
private JTextField jTextFieldmsg;
private ClientAlreadyConnect pClient;
public ServerThread(JTextArea jTextArea,JButton jButton,JTextField jTextFieldmsg,ClientAlreadyConnect pClient){
this.jTextArea =jTextArea;
this.jButton = jButton;
this.jTextFieldmsg = jTextFieldmsg;
this.pClient = pClient;
}
public ServerThread(Socket sc,JTextArea jTextArea,JButton jButton,JTextField jTextFieldmsg,ClientAlreadyConnect pClient){
this.client = sc;
this.jTextArea = jTextArea;
this.jButton = jButton;
this.jTextFieldmsg = jTextFieldmsg;
this.pClient = pClient;
}
public void sendMsg2Me(String msg) throws Exception{
byte[] data = msg.getBytes();
out.write(data);
out.flush();
}
public void run(){
//在线程run中调用处理节点的方法
process(this.client);
}
private void process(Socket client) {
try{
JbuttonmsgListener jbmsgListener = new JbuttonmsgListener(jTextFieldmsg,jTextArea,this);
jButton.addActionListener(jbmsgListener);
InputStream ins = client.getInputStream();
out = client.getOutputStream();
String string = " Hello,欢迎来的香煎马鲛鱼的服务器\r\n";
this.sendMsg2Me(string);
//调用读取字符串的方法,从输入流读取一个字符串
String insputS = readString(ins);
while(!insputS.equals("bye")){
string = "(客户端"+pClient.getName()+"消息)";
this.sendMsg2Me(string);
jTextArea.append(string);
insputS = readString(ins);
String string2 = null;
//System.out.println(string2);
//this.sendMsg2Me(insputS);
}
string = "大爷走好~~以后常来玩啊~~\r\n";
this.sendMsg2Me(string);
client.close();
insputS = readString(ins);
}
catch(Exception e){
}
}
private String readString(InputStream ins) throws Exception{
StringBuffer stb = new StringBuffer();
int i = ins.read();
char c = 0;
while(c!=13){
c = (char)i;
stb.append(c);
i = ins.read();
}
//将读到的字节组转为字符串,并调用trim去掉尾部的空格
String inputS =stb.toString().trim();
jTextArea.append(inputS);
return inputS;
}
}
//将发送信息的代码包装在一个方法中
package Connect;
import java.util.List;
import java.util.ArrayList;
public class Configstatic {
public static List<ClientAlreadyConnect> allClient = new ArrayList<ClientAlreadyConnect>();
}
package Connect;
import java.io.DataInputStream;
import java.io.InputStream;
import java.io.OutputStream;
import java.net.ServerSocket;
import java.net.Socket;
import java.util.Random;
import javax.swing.JButton;
import javax.swing.JTextArea;
import javax.swing.JTextField;
public class ServerThread extends Thread{
private Socket client;//线程对象要处理的连结变量
private OutputStream out;
private JTextArea jTextArea;
private JButton jButton;
private JTextField jTextFieldmsg;
private ClientAlreadyConnect pClient;
public ServerThread(JTextArea jTextArea,JButton jButton,JTextField jTextFieldmsg,ClientAlreadyConnect pClient){
this.jTextArea =jTextArea;
this.jButton = jButton;
this.jTextFieldmsg = jTextFieldmsg;
this.pClient = pClient;
}
public ServerThread(Socket sc,JTextArea jTextArea,JButton jButton,JTextField jTextFieldmsg,ClientAlreadyConnect pClient){
this.client = sc;
this.jTextArea = jTextArea;
this.jButton = jButton;
this.jTextFieldmsg = jTextFieldmsg;
this.pClient = pClient;
}
public void sendMsg2Me(String msg) throws Exception{
byte[] data = msg.getBytes();
out.write(data);
out.flush();
}
public void run(){
//在线程run中调用处理节点的方法
process(this.client);
}
private void process(Socket client) {
try{
JbuttonmsgListener jbmsgListener = new JbuttonmsgListener(jTextFieldmsg,jTextArea,this);
jButton.addActionListener(jbmsgListener);
InputStream ins = client.getInputStream();
out = client.getOutputStream();
String string = " Hello,欢迎来的香煎马鲛鱼的服务器\r\n";
this.sendMsg2Me(string);
//调用读取字符串的方法,从输入流读取一个字符串
String insputS = readString(ins);
while(!insputS.equals("bye")){
string = "(客户端"+pClient.getName()+"消息)";
this.sendMsg2Me(string);
jTextArea.append(string);
insputS = readString(ins);
String string2 = null;
//System.out.println(string2);
//this.sendMsg2Me(insputS);
}
string = "大爷走好~~以后常来玩啊~~\r\n";
this.sendMsg2Me(string);
client.close();
insputS = readString(ins);
}
catch(Exception e){
}
}
private String readString(InputStream ins) throws Exception{
StringBuffer stb = new StringBuffer();
int i = ins.read();
char c = 0;
while(c!=13){
c = (char)i;
stb.append(c);
i = ins.read();
}
//将读到的字节组转为字符串,并调用trim去掉尾部的空格
String inputS =stb.toString().trim();
jTextArea.append(inputS);
return inputS;
}
}
//将发送信息的代码包装在一个方法中
客户端:
客户端需要的过程:
Socket client=new Socket(“服务器IP”,服务器端口);
只要如上代码执行成功,就算一个客户端连结上了服务器,接下来的流程和服务器端得到
Socket对象后的处理方式相同---从Socket对象上得到输入输出流;
注意:如果断开服务器时报错,那么这个错误是正常出现的,不是程序问题;
测试过程中,先关客户端,再关服务器,不然会报很多错误,也许还会导致编译器无法正常运行,一定注意~~~
package Client;
import java.awt.BorderLayout;
import java.awt.Dimension;
import javax.swing.JButton;
import javax.swing.JFrame;
import javax.swing.JLabel;
import javax.swing.JPanel;
import javax.swing.JTextArea;
import javax.swing.JTextField;
public class Clientserver extends JFrame{
public void Clientjfr(){
this.setSize(500,400);
this.setTitle("呵呵客户端");
this.setDefaultCloseOperation(3);
this.setLocationRelativeTo(null);
//北部连接服务器
JLabel jLabelIp = new JLabel("Ip地址:");
JLabel jLabel = new JLabel("端口号:");
JButton jButton = new JButton("连接服务器");
JTextField jTextFieldIp = new JTextField("localhost");
JTextField jTextField = new JTextField("8090");
jTextFieldIp.setPreferredSize(new Dimension(100,30));
jTextField.setPreferredSize(new Dimension(100,30));
JPanel northjPanel = new JPanel();
//northjPanel.setSize(new Dimension(400,400));
northjPanel.add(jLabelIp);
northjPanel.add(jTextFieldIp);
northjPanel.add(jLabel);
northjPanel.add(jTextField);
northjPanel.add(jButton);
this.add(northjPanel,BorderLayout.NORTH);
//中部文本输入框:
JPanel jPanel = new JPanel();
JButton jButtoncenter = new JButton("发布消息");
JTextField jTextFieldcenter = new JTextField();
jTextFieldcenter.setPreferredSize(new Dimension(360,30));
jTextFieldcenter.setHorizontalAlignment(JTextField.LEFT);
jPanel.add(jButtoncenter);
jPanel.add(jTextFieldcenter);
this.add(jPanel,BorderLayout.CENTER);
//南部显示框
String abcString = "收到的信息在此处显示";
JPanel southjPanel = new JPanel();
JTextArea jTextAreasouth = new JTextArea();
jTextAreasouth.setPreferredSize(new Dimension(410,270));
jTextAreasouth.append(abcString);
southjPanel.add(jTextAreasouth);
this.add(southjPanel,BorderLayout.SOUTH);
this.setVisible(true);
JButtonListener jbListener = new JButtonListener(jTextField,jTextFieldIp,jTextFieldcenter,jTextAreasouth,jButtoncenter);
jButton.addActionListener(jbListener);
}
}
package Client;
import java.io.BufferedReader;
import java.io.InputStream;
import java.io.InputStreamReader;
import java.io.OutputStream;
import java.net.Socket;
import javax.swing.JTextArea;
public class Clientsotfware extends Thread {
private JTextArea jTextAreasouth;
private String ConnectIp;
private int port;
private OutputStream ouStream;// 到服务器的输出流
private InputStream ins;// 到服务器的输入流
public Clientsotfware(String ConnectIp, int port,JTextArea jTextAreasouth) {
this.ConnectIp = ConnectIp;
this.port = port;
this.jTextAreasouth = jTextAreasouth;
}
public boolean ConnectTerminal() {
try {
// 创建一个服务器端的Socket对象
Socket client = new Socket(ConnectIp, port);
ins = client.getInputStream();
// bfReader = new BufferedReader(new InputStreamReader(inStream));
ouStream = client.getOutputStream();
return true;
} catch (Exception e) {
}
return false;
}
public void run() {
while (true) {
readFromServer();
}
}
public void readFromServer() {
try {
String input = readString(ins);
System.out.println(input);
jTextAreasouth.append(input);
} catch (Exception e) {
e.printStackTrace();
}
}
public void senMsg(String msg) {
try {
msg += "\r\n";
this.ouStream.write(msg.getBytes());
//System.out.println("客户端要发送的消息:"+msg);
this.ouStream.flush();
jTextAreasouth.append("客户端要发送的消息"+msg);
} catch (Exception e) {
e.printStackTrace();
}
}
public String readString(InputStream ins) throws Exception {
StringBuffer stb = new StringBuffer();
int i = ins.read();
char c = 0;
while (c != 13) {
stb.append(c);
i = ins.read();
c = (char) i;
}
String inputs = stb.toString().trim();
return inputs;
}
}
package Client;
import java.awt.event.ActionEvent;
import java.awt.event.ActionListener;
import javax.swing.JButton;
import javax.swing.JTextArea;
import javax.swing.JTextField;
public class JButtonListener implements ActionListener{
private JTextArea jTextAreasouth=null;
private JTextField jTextField=null;
private JTextField jTextFieldIp=null;
private JTextField jTextFieldmsg = null;
private JButton jButton=null;
public JButtonListener (JTextField jTextField,JTextField jTextFieldIp,JTextField jTextFieldmsg,JTextArea jTextAreasouth,JButton jButton){
this.jTextField = jTextField;
this.jTextFieldIp = jTextFieldIp;
this.jTextAreasouth = jTextAreasouth;
this.jTextFieldmsg = jTextFieldmsg;
this.jButton = jButton;
}
@Override
public void actionPerformed(ActionEvent e) {
// TODO Auto-generated method stub
int number=0;
String stnumber ="";
String str="0";
stnumber = jTextField.getText();
number = Integer.parseInt(stnumber);
str = jTextFieldIp.getText();
JframeThread jfThread = new JframeThread(number,str,jTextFieldmsg,jTextAreasouth,jButton);
jfThread.start();
}
}
package Client;
import java.util.Scanner;
import javax.swing.JButton;
import javax.swing.JTextArea;
import javax.swing.JTextField;
public class JframeThread extends Thread{
private JTextArea jTextAreasouth;
private JTextField jTextFieldmsg;
private JButton jButton;
private int number;
private String str;
public JframeThread(int number,String str,JTextField jTextFieldmsg,JTextArea jTextAreasouth,JButton jButton){
this.number = number;
this.str = str;
this.jTextFieldmsg = jTextFieldmsg;
this.jTextAreasouth =jTextAreasouth;
this.jButton = jButton;
}
public void run(){
String msg=null;
Clientsotfware clientsotfware = new Clientsotfware(str,number,jTextAreasouth);
if(clientsotfware.ConnectTerminal()){
clientsotfware.start();
System.out.println("输入要发送的消息:");
SenMsgListener senListener = new SenMsgListener(clientsotfware,jTextFieldmsg);
jButton.addActionListener(senListener); }
}
}
package Client;
import java.util.Scanner;
publicclass netClient {
/**
*@paramargs
*/
publicstaticvoid main(String[] args) {
// TODO Auto-generated method stub
Clientserver clserver = new Clientserver();
clserver.Clientjfr();
}
}
package Client;
import java.awt.event.ActionEvent;
import java.awt.event.ActionListener;
import javax.swing.JTextField;
public class SenMsgListener implements ActionListener{
private Clientsotfware clientsotfware;
private JTextField jTextFieldmsg;
public SenMsgListener(Clientsotfware clientsotfware,JTextField jTextFieldmsg) {
// TODO Auto-generated constructor stub
this.clientsotfware = clientsotfware;
this.jTextFieldmsg = jTextFieldmsg;
}
@Override
public void actionPerformed(ActionEvent e) {
// TODO Auto-generated method stub
clientsotfware.senMsg(jTextFieldmsg.getText());
jTextFieldmsg.setText("");
}
}
相关推荐
在本例中,"口袋微博服务器客户端代码"的源码揭示了应用如何与服务器进行数据交换,包括登录验证、发布/获取微博、用户交互等功能的实现。通过阅读和分析源码,我们可以学习到网络请求、数据解析、JSON格式处理、...
本文将围绕“Android源码——口袋微博服务器客户端代码”这一主题,深入探讨其背后的实现原理和关键知识点,以帮助开发者更好地理解和应用相关技术。 首先,我们要知道Android应用程序通常由Java或Kotlin编写,而...
这篇内容将深入解析《Android源码——口袋微博服务器客户端代码》这一主题,主要涉及Android应用程序开发,特别是针对微博服务的客户端实现。我们将探讨以下几个关键知识点: 1. **Android应用程序架构**: ...
在"QT——服务器+客户端进行tcp通信代码.rar"这个压缩包中,包含了一个客户端(client)和一个服务器端(server)的工程,这让我们有机会深入理解QT如何实现TCP/IP通信。 首先,TCP(传输控制协议)是互联网协议栈...
这篇文档将深入解析《安卓Android源码——口袋微博服务器客户端代码》的相关知识点,主要围绕安卓应用开发、源码分析以及服务器通信技术展开。 首先,我们要理解的是“安卓Android”。安卓是一种基于Linux内核的...
《安卓Android源码——口袋微博 服务器 客户端代码》是针对移动应用开发者的一份珍贵资源,它包含了实现一个类似口袋微博应用的完整代码结构,涵盖了客户端与服务器的交互。这份源码提供了深入理解Android应用程序...
内容摘要:使用“epoll+线程池”技术,通过makefile管理的简单项目——“服务器与客户端完成通信并处理小型业务” 技术涉及:网络初始化、epoll模型、线程池、线程同步、互斥锁 适用人群:在校大学生,并对网络通信...
在UDP通信中,客户端和服务器端都需要实现特定的程序来处理图像数据的发送和接收。`UDPTest`可能是一个客户端程序,用于读取本地图像文件并将其打包成UDP数据报文,然后通过网络发送到服务器端。`UDPServer`则可能是...
2. **网络通信**:微博客户端需要频繁地与服务器交互,获取和发送数据。这涉及到HTTP请求、JSON解析、WebSocket等网络技术。源码中可能使用了OkHttp、Retrofit等第三方库,我们可以学习到如何高效地进行网络通信,...
通过学习和分析"口袋微博服务器客户端代码",开发者不仅可以深入了解Android应用的开发流程,还能掌握如何实现社交应用的核心功能,如用户登录、发布和浏览微博、评论互动等。同时,这也是一个实践安卓网络编程、...
服务器与客户端小程序,服务器端是MyTcp.java ,客户端是:MyClient.java,这里是客户端,由于csdn不支持将两个同时上传,所以说我只好将其分开了。
在Golang中,可以使用标准库"net"进行网络通信,"encoding/json"或"gob"进行数据序列化,实现客户端与服务器之间的数据交换。为了优化性能,客户端可能会采用异步I/O模型,利用goroutine处理网络事件,避免阻塞主线...
在本项目中,我们主要探讨如何使用Android客户端与Web服务器进行交互,实现一个基本的登录功能。这个项目包括服务端、数据库以及Android客户端三个部分,旨在帮助开发者理解客户端与服务器之间的数据通信流程。 1. ...
2. **网络通信**:客户端通常使用HTTP或HTTPS协议与服务器进行通信,此处可能采用了OkHttp或者Volley等网络库。在微博应用中,会涉及到登录验证、获取新闻信息、发布和转发微博等一系列网络请求。分析这部分代码,有...
### 客户端与服务器端通信基础 在聊天工具中,客户端用于发送和接收消息,服务器端则负责接收客户端连接并转发消息。在TCP/IP协议栈上,通常使用TCP协议建立可靠的连接。客户端首先发起连接请求,服务器端监听并接受...
在TCP应用中,客户端与服务器端的通信是互联网服务的基础,涉及多个关键概念和技术。 首先,TCP是面向连接的,这意味着在数据传输前,客户端和服务器端需要先建立一个连接。这个过程通常被称为三次握手(Three-way ...