通过Java中的Socket技术编写能够进行双向通信的客户端和服务器,为了能够同时进行消息的发送和接受,在服
SocketClient1java内容如下:
package compolyphyllasocket;
import javaioBufferedReader;
import javaioIOException;
import javaioInputStreamReader;
import javaioPrintWriter;
import javanetSocket;
import javanetUnknownHostException;
public class SocketClient1 {
private Socket socket;
public SocketClient1() {
try {
socket = new Socket("127001", 2222);
} catch (UnknownHostException e) {
eprintStackTrace();
} catch (IOException e) {
eprintStackTrace();
}
}
/
@param args
/
public static void main(String[] args) {
new SocketClient1()startClient();
}
public void startClient() {
new Thread(new ClientReader(socket))start();
new Thread(new ClientWriter(socket))start();
}
}
class ClientReader implements Runnable {
private Socket socket;
public ClientReader(Socket socket) {
thissocket = socket;
}
public void run() {
BufferedReader br = getReader();
String msg = null;
try {
while ((msg = brreadLine()) != null) {
Systemoutprintln("client:" + msg);
}
} catch (IOException e) {
eprintStackTrace();
} finally {
try {
if (br != null)
brclose();
if (socket != null)
socketclose();
} catch (IOException e) {
// TODO Auto-generated catch block
eprintStackTrace();
}
}
}
private BufferedReader getReader() {
try {
return new BufferedReader(new InputStreamReader(socket
getInputStream()));
} catch (IOException e) {
eprintStackTrace();
}
return null;
}
}
class ClientWriter implements Runnable {
private Socket socket;
public ClientWriter(Socket socket) {
thissocket = socket;
}
public void run() {
PrintWriter pw = getWriter();
BufferedReader br = new BufferedReader(new InputStreamReader(Systemin));
String str = null;
try {
while ((str = brreadLine()) != null) {
pwprintln(str);
pwflush();
}
} catch (IOException e) {
eprintStackTrace();
} finally {
if (pw != null)
pwclose();
try {
if (socket != null)
socketclose();
} catch (IOException e) {
// TODO Auto-generated catch block
eprintStackTrace();
}
}
}
private PrintWriter getWriter() {
try {
return new PrintWriter(socketgetOutputStream());
} catch (IOException e) {
eprintStackTrace();
}
return null;
}
}
SocketServer1java内容如下:
package compolyphyllasocket;
import javaioBufferedReader;
import javaioIOException;
import javaioInputStreamReader;
import javaioPrintWriter;
import javanetServerSocket;
import javanetSocket;
public class SocketServer1 {
private ServerSocket ss;
public SocketServer1() {
try {
ss = new ServerSocket(2222);
} catch (IOException e) {
eprintStackTrace();
}
}
public static void main(String[] args) {
new SocketServer1()startServer();
}
public void startServer() {
try {
while (true) {
Socket s = ssaccept();
new Thread(new ServerReader(s))start();
new Thread(new ServerWriter(s))start();
}
} catch (IOException e) {
eprintStackTrace();
}
}
}
class ServerReader implements Runnable {
private Socket socket;
public ServerReader(Socket socket) {
thissocket = socket;
}
public void run() {
BufferedReader br = getReader();
String msg = null;
try {
while((msg = brreadLine()) != null) {
Systemoutprintln("server:" + msg);
}
} catch (IOException e) {
eprintStackTrace();
} finally {
try {
if(br != null)
brclose();
if(socket != null)
socketclose();
} catch (IOException e) {
// TODO Auto-generated catch block
eprintStackTrace();
}
}
}
private BufferedReader getReader() {
try {
return new BufferedReader(new InputStreamReader(socketgetInputStream()));
} catch (IOException e) {
eprintStackTrace();
}
return null;
}
}
class ServerWriter implements Runnable {
private Socket socket;
public ServerWriter(Socket socket) {
thissocket = socket;
}
public void run() {
PrintWriter pw = getWriter();
BufferedReader br = new BufferedReader(new InputStreamReader(Systemin));
String str = null;
try {
while((str = brreadLine()) != null) {
pwprintln(str);
pwflush();
}
} catch (IOException e) {
eprintStackTrace();
} finally {
if (pw != null)
pwclose();
try {
if (socket != null)
socketclose();
} catch (IOException e) {
// TODO Auto-generated catch block
eprintStackTrace();
}
}
}
private PrintWriter getWriter() {
try {
return new PrintWriter(socketgetOutputStream());
} catch (IOException e) {
eprintStackTrace();
}
return null;
}
}
如下:
<form action="homejsp" method=post>
<form action="Sreach" method="post">
<input type="text" style="height: 24px;width: 200px" name="m">
<select name="n">
<option value="TitleName">标题</option>
<option value="Creator" >作者</option>
<option value="Type" >类别</option>
<option value="id" >ID</option>
<input type="submit" value="搜索">
</select>
面向对象:其实是现实世界模型的自然延伸。现实世界中任何实体都可以看作是对象。对象之间通过消息相互作用。另外,现实世界中任何实体都可归属于某类事物,任何对象都是某一类事物的实例。如果说传统的过程式编程语言是以过程为中心以算法为驱动的话,面向对象的编程语言则是以对象为中心以消息为驱动。用公式表示,过程式编程语言为:程序=算法+数据;面向对象编程语言为:程序=对象+消息。 所有面向对象编程语言都支持三个概念:封装、多态性和继承,Java也不例外。现实世界中的对象均有属性和行为,映射到计算机程序上,属性则表示对象的数据,行为表示对象的方法(其作用是处理数据或同外界交互)。所谓封装,就是用一个自主式框架把对象的数据和方法联在一起形成一个整体。可以说,对象是支持封装的手段,是封装的基本单位。Java语言的封装性较强,因为Java无全程变量,无主函数,在Java中绝大部分成员是对象,只有简单的数字类型、字符类型和布尔类型除外。而对于这些类型,Java也提供了相应的对象类型以便与其他对象交互操作。
可移植性:就是在这个系统上作的程序经过一次编译后可以移植到别的系统上解释执行,只要经过简单的粘贴和复制就行了,不影响程序的效果
安全性:在 iSeries 服务器上运行的大多数 Java(TM) 程序是应用程序,而不是 applet,所以“砂箱”安全性模型对它们不起限制作用。从安全性的观点看,Java 应用程序所受的安全性限制与 iSeries 服务器上的任何其它程序相同。要在 iSeries 服务器上运行 Java 程序,您必须对集成文件系统中的类文件具有权限。程序一旦启动,它就在该用户权限控制下运行。 您可以使用沿用权限来访问具有运行程序的用户的权限和程序拥有者权限的对象。沿用权限临时地将用户原先无权访问的对象的权限授予用户。
并发性:JAVA支持多线程技术,就是多个线程并行机制,多线程是Java的一个重要方法,特别有利于在程序中实现并发任务Java提供Thread线程类,实现了多线程的并发机制
j2se j2ee j2me
J2SE商业版本,标准版本 (Java2 Standard Edition) 定位在客户端,主要用于桌面应用软件的编程。
J2EE Java2平台企业版,企业级网站设计
J2ME在嵌入式系统上应用
类表示同一类事物的集合表示,就像是一个模板,它具有该同种对象的所有表现,它包含类的属性和方法,如举一个人的类,那么这个类有姓名 年龄 性别 等(属性),它会说话 会吃东西 等(方法),这就是一个简单的类,那么对象呢假设一个张三,一个李四,可能他们说话,吃东西方法类似,但是他们的姓名,年龄 性别等不一定是相同的,这就是一个类的具体的一个对象
Java的命名习惯:
1、包名中的字母一律小写。xxxyyyzzz
2、类名、接口名应当使用名词,每个单词的首字母大写。XxxYyyZzz
3、方法名,第一个单词小写,后面每个单词的首字母大写。xxxYyyZzz
4、变量名,第一个单词小写,后面第个单词的首字母大写。xxxYyyZzz
5、常量名中的每个字母一律大写。XXXYYYZZZ
所谓函数重载是指同一个函数名可以对应着多个函数的实现。例如,可以给函数名add()定义多个函数实现,该函数的功能是求和,即求两个操作数的和。其中,一个函数实现是求两个int型数之和,另一个实现是求两个浮点型数之和,再一个实现是求两个复数的和。每种实现对应着一个函数体,这些函数的名字相同,但是函数的参数的类型不同。这就是函数重载的概念。
写个简单点的服务器跟客服端就行了我写了个很简单的,只能在一个客户端跟一个服务器通信,在控制台输入下面这个是服务器import javaio;
import javanet;
import javautilScanner;public class Server
{
public static void main(String[] args)
{
try {
ServerSocket server=new ServerSocket(8888);//定义客户端的端口号
Socket client=serveraccept();//定义一个Socket对象
InputStream is=clientgetInputStream();//服务器接受信息输入流,也就是接受从服务器段发送过来的消息
BufferedReader br=new BufferedReader(new InputStreamReader(is));//用bufferedreader包装下输入流
OutputStream os=clientgetOutputStream();//这是用来给服务器发送消息的输出流
PrintStream ps=new PrintStream(os);
Scanner scanner=new Scanner(Systemin);//从键盘输入字符串
boolean flag=true;//定义一个死循环,让服务器不停的接受从客户端发送来的字符串
while(flag)
{
String s=brreadLine();//s是从客户端接受到得字符串
Systemoutprintln(s);
String s2=scannernextLine();//s2是写给客户端的字符串
psprintln(s2); //给客户端发送你写的东西
}
clientclose();
} catch (IOException e) {//try 跟catch你不用管,这是用来处理异常的,就是固定格式
eprintStackTrace();
}
}
} 下面是客户端import javaio;
import javanet;
import javautilScanner;public class Client
{ public static void main(String[] args)
{
try
{
Socket client=new Socket("192168----",8888);//IP地址是个字符串,端口号是个整数,这个端口号要跟前面你写的那个一样,还有IP地址,写你的机器的IP地址
InputStream is=clientgetInputStream();//这边的两个流跟上面服务器的差不多的作用
BufferedReader bf=new BufferedReader(new InputStreamReader(is));
OutputStream os=clientgetOutputStream();
PrintStream ps=new PrintStream(os);
Scanner scanner=new Scanner(Systemin);
boolean flag=true;
while(flag)//这句话可以让客户端不停的说话
{
String s2=scannernextLine();
psprintln(s2);
String s=bfreadLine();
Systemoutprintln(s); }
clientclose();
}
catch (UnknownHostException e)
{
eprintStackTrace();
}
catch (IOException e)
{
eprintStackTrace();
} }}
你可以在每个用户连上服务器端时,都发送一个消息,就是用4个字节表示是用户的ID,并将与用户通信的socket,用一个HashMap存储起来,而不是用LinkList。
后面如果A发送消息给C,就把A的前四个字节(即ID)取出来,在HashMap中找到与C通信的socket,然后把消息通过socket发送出去····
这部分代码应该很容易实现的,Socket通信这东西,理清了思路就很好弄了~~
下面是一个简单的通讯实例,进行Server和Client之间的文件传输。。如果是简单的文本传输的话简化掉文本操作的内容即可。。
1服务器端
package sterning;
import javaioBufferedInputStream;
import javaioDataInputStream;
import javaioDataOutputStream;
import javaioFile;
import javaioFileInputStream;
import javanetServerSocket;
import javanetSocket;
public class ServerTest {
int port = 8821;
void start() {
Socket s = null;
try {
ServerSocket ss = new ServerSocket(port);
while (true) {
// 选择进行传输的文件
String filePath = "D:\\librar";
File fi = new File(filePath);
Systemoutprintln("文件长度:" + (int) filength());
// public Socket accept() throws
// IOException侦听并接受到此套接字的连接。此方法在进行连接之前一直阻塞。
s = ssaccept();
Systemoutprintln("建立socket链接");
DataInputStream dis = new DataInputStream(new BufferedInputStream(sgetInputStream()));
disreadByte();
DataInputStream fis = new DataInputStream(new BufferedInputStream(new FileInputStream(filePath)));
DataOutputStream ps = new DataOutputStream(sgetOutputStream());
//将文件名及长度传给客户端。这里要真正适用所有平台,例如中文名的处理,还需要加工,具体可以参见Think In Java 4th里有现成的代码。
pswriteUTF(figetName());
psflush();
pswriteLong((long) filength());
psflush();
int bufferSize = 8192;
byte[] buf = new byte[bufferSize];
while (true) {
int read = 0;
if (fis != null) {
read = fisread(buf);
}
if (read == -1) {
break;
}
pswrite(buf, 0, read);
}
psflush();
// 注意关闭socket链接哦,不然客户端会等待server的数据过来,
// 直到socket超时,导致数据不完整。
fisclose();
sclose();
Systemoutprintln("文件传输完成");
}
} catch (Exception e) {
eprintStackTrace();
}
}
public static void main(String arg[]) {
new ServerTest()start();
}
}
2socket的Util辅助类
package sterning;
import javanet;
import javaio;
public class ClientSocket {
private String ip;
private int port;
private Socket socket = null;
DataOutputStream out = null;
DataInputStream getMessageStream = null;
public ClientSocket(String ip, int port) {
thisip = ip;
thisport = port;
}
/ //
创建socket连接
@throws Exception
exception
/
public void CreateConnection() throws Exception {
try {
socket = new Socket(ip, port);
} catch (Exception e) {
eprintStackTrace();
if (socket != null)
socketclose();
throw e;
} finally {
}
}
public void sendMessage(String sendMessage) throws Exception {
try {
out = new DataOutputStream(socketgetOutputStream());
if (sendMessageequals("Windows")) {
outwriteByte(0x1);
outflush();
return;
}
if (sendMessageequals("Unix")) {
outwriteByte(0x2);
outflush();
return;
}
if (sendMessageequals("Linux")) {
outwriteByte(0x3);
outflush();
} else {
outwriteUTF(sendMessage);
outflush();
}
} catch (Exception e) {
eprintStackTrace();
if (out != null)
outclose();
throw e;
} finally {
}
}
public DataInputStream getMessageStream() throws Exception {
try {
getMessageStream = new DataInputStream(new BufferedInputStream(socketgetInputStream()));
return getMessageStream;
} catch (Exception e) {
eprintStackTrace();
if (getMessageStream != null)
getMessageStreamclose();
throw e;
} finally {
}
}
public void shutDownConnection() {
try {
if (out != null)
outclose();
if (getMessageStream != null)
getMessageStreamclose();
if (socket != null)
socketclose();
} catch (Exception e) {
}
}
}
3客户端
package sterning;
import javaioBufferedOutputStream;
import javaioDataInputStream;
import javaioDataOutputStream;
import javaioFileOutputStream;
public class ClientTest {
private ClientSocket cs = null;
private String ip = "localhost";// 设置成服务器IP
private int port = 8821;
private String sendMessage = "Windwos";
public ClientTest() {
try {
if (createConnection()) {
sendMessage();
getMessage();
}
} catch (Exception ex) {
exprintStackTrace();
}
}
private boolean createConnection() {
cs = new ClientSocket(ip, port);
try {
csCreateConnection();
Systemoutprint("连接服务器成功!" + "\n");
return true;
} catch (Exception e) {
Systemoutprint("连接服务器失败!" + "\n");
return false;
}
}
private void sendMessage() {
if (cs == null)
return;
try {
cssendMessage(sendMessage);
} catch (Exception e) {
Systemoutprint("发送消息失败!" + "\n");
}
}
private void getMessage() {
if (cs == null)
return;
DataInputStream inputStream = null;
try {
inputStream = csgetMessageStream();
} catch (Exception e) {
Systemoutprint("接收消息缓存错误\n");
return;
}
try {
//本地保存路径,文件名会自动从服务器端继承而来。
String savePath = "E:\\";
int bufferSize = 8192;
byte[] buf = new byte[bufferSize];
int passedlen = 0;
long len=0;
savePath += inputStreamreadUTF();
DataOutputStream fileOut = new DataOutputStream(new BufferedOutputStream(newBufferedOutputStream(new FileOutputStream(savePath))));
len = inputStreamreadLong();
Systemoutprintln("文件的长度为:" + len + "\n");
Systemoutprintln("开始接收文件!" + "\n");
while (true) {
int read = 0;
if (inputStream != null) {
read = inputStreamread(buf);
}
passedlen += read;
if (read == -1) {
break;
}
//下面进度条本为图形界面的prograssBar做的,这里如果是打文件,可能会重复打印出一些相同的百分比
Systemoutprintln("文件接收了" + (passedlen 100/ len) + "%\n");
fileOutwrite(buf, 0, read);
}
Systemoutprintln("接收完成,文件存为" + savePath + "\n");
fileOutclose();
} catch (Exception e) {
Systemoutprintln("接收消息错误" + "\n");
return;
}
}
public static void main(String arg[]) {
new ClientTest();
}
}
import javanet;
import javaio;
public class Server {
public static void main(String[] args) throws IOException {
String s = "";//用stringbuffer试试
String s1 = "";
ServerSocket server = new ServerSocket(60000);
Systemoutprintln("可以开始通信");
try {
Socket socket = serveraccept();
Systemoutprintln(socket);
InputStream is = socketgetInputStream();
OutputStream out = socketgetOutputStream();
BufferedReader bfr = new BufferedReader(new InputStreamReader(is));
PrintWriter pw = new PrintWriter(new OutputStreamWriter(out));
BufferedReader br = new BufferedReader(new InputStreamReader(Systemin));
while (true) {
s = bfrreadLine();
Systemoutprintln("客户端对我说:" + s);//读取客户端信息并输出
if("bye"equals(s)) {
pwprintln("bye");
pwflush();
break;
}
s1 = brreadLine();
pwprintln(s1);
pwflush();
Systemoutprintln("我对客户端说:" + s1);
}
socketclose();
} catch (IOException e) {
eprintStackTrace();
}
serverclose();
}
class Reader extends Thread {
public void run() {
while (true) {
}
}
}
}
import javanet;
import javaio;
public class Talk {
static InputStream is = null;
static OutputStream out;
static BufferedReader bfr;
static PrintWriter pw;
static BufferedReader pin;
public static void main(String[] args) throws IOException {
Socket socket = new Socket(InetAddressgetByName("localhost"), 60000);
Systemoutprintln(socket);
try {
is = socketgetInputStream();
out = socketgetOutputStream();
bfr = new BufferedReader(new InputStreamReader(is));
pw = new PrintWriter(new OutputStreamWriter(out));
pin = new BufferedReader(new InputStreamReader(Systemin));
new Controlaa()start();
while (true) {
String s1 = bfrreadLine();
Systemoutprintln("服务器对我说:" + s1);//读取服务器端发送的信息
if (s1equals("bye")) {
break;
}
}
socketclose();
} catch (IOException e) {
eprintStackTrace();
}
}
static class Controlaa extends Thread {
@Override
public void run() {
while (true) {
String s = "";
try {
s = pinreadLine();
} catch (IOException ex) {
exprintStackTrace();
}
Systemoutprintln("我对服务器说:" + s);
pwprintln(s);
pwflush();
}
}
}
}
简单搞了下,读取控制台输入和读取socket都是阻塞操作
服务器告知双方对方的ip地址,并协调由哪一方主动连接。
如 协调结果是: 把c2的地址告诉c1,让c1主动连接c2,让c2打开端口等待连接。
要考虑认证问题,比如c2如何知道连接上来的是c1,而不是其他人,就需要有认证机制。
另外要考虑内网问题。由于从外部连接内网里面的IP地址是相当繁琐复杂的,所以需要特别的机制处理。
0条评论