好久没有写javaeye博客了,最近写了个TCP Socket编程,和大家一起分享!
聊天原理:启动TCP服务端,等待客户端连接,当客户端连接到服务端后,服务端创建一个线程针对该客户端进行读写,服务端继续在指定端口监听客户端连接。客户端连接成功后,创建写线程和读线程,来与服务器端进行通信。服务器端线程接收到客户端的信息,再把该信息转发给消息的目的地客户端。目的地客户端通过发送线程发送消息给服务器端,服务器端接收到消息,再把消息转发给目的地客户端。服务器端线程并不会主动地发送消息给客户端,服务器端线程只是在中转客户端发送过来的信息,把消息发送给指定的目的地客户端而已。
如何实现从客户端A发送消息给客户端B呢?
1、客户端A通过写线程,写入消息到服务器端
2、服务器端接收到客户端A的消息,并解析消息内容,得知消息是要发送给客户端B,服务器端线程写入消息给客户端B
3、客户端B读取线程读取到服务器线程发送来的数据
这样的就完成了从客户端A发送消息到客户端B,通过客户端B也通过同样的方式发送消息给客户端A。完成双向通信。
服务端:
package com.guchao.chat;
import java.io.DataInputStream;
import java.io.DataOutputStream;
import java.io.IOException;
import java.net.ServerSocket;
import java.net.Socket;
import java.util.HashMap;
import java.util.Iterator;
import java.util.Map;
public class TCPServer {
private Map<String, Socket> sockets = new HashMap<String, Socket>();
/**
* @param args
* @throws IOException
*/
public static void main(String[] args) throws IOException {
new TCPServer().go();
}
public void go(){
ServerSocket ss = null;
try {
ss = new ServerSocket(8888);
System.out.println("服务器启动成功,在8888端口监听用户连接!");
} catch (IOException e1) {
e1.printStackTrace();
}
Socket s = null;
int i = 0;
while(true){
try {
s = ss.accept();
String clientName = "Client_"+(++i);
sockets.put(clientName, s);
sendMessageToOtherClients(clientName);
System.out.println(clientName+"连接到服务器!");
} catch (IOException e) {
e.printStackTrace();
}
ReadAndWriteThread t = new ReadAndWriteThread(s);
new Thread(t).start();
}
}
private void sendMessageToOtherClients(String clientName) {
if(sockets != null && sockets.size() > 0){
for (Iterator<String> iterator = sockets.keySet().iterator(); iterator.hasNext();) {
String key = (String) iterator.next();
Socket s = sockets.get(key);
try {
DataOutputStream dos = new DataOutputStream(s.getOutputStream());
dos.writeUTF(clientName+"已经登陆了服务器!");
} catch (IOException e) {
e.printStackTrace();
}
}
}
}
class ReadAndWriteThread implements Runnable{
private DataInputStream dis = null;
public ReadAndWriteThread(Socket s){
try {
dis = new DataInputStream(s.getInputStream());
} catch (IOException e) {
e.printStackTrace();
}
}
@Override
public void run() {
String str = "";
while(true){
try {
/**
* 定义消息格式为hello,jjkdfjaf*客户端名称*
* 例如:hello,zhangsan*Client_2*
* 表示消息hello,zhangsan发送给Client_2
*/
str = dis.readUTF();
if("bye".equals(str))
break;
sendMessageToClient(str);
} catch (IOException e) {
e.printStackTrace();
}
}
}
}
private void sendMessageToClient(String str){
int startPosition = str.lastIndexOf("*", str.lastIndexOf("*")-1);
int endPosition = str.lastIndexOf("*");
if(startPosition > 0 && endPosition > 0 && endPosition > startPosition){
String clientName = str.substring(startPosition+1, endPosition);
Socket s = sockets.get(clientName);
DataOutputStream dos = null;
try {
if(s != null){
dos = new DataOutputStream(s.getOutputStream());
dos.writeUTF(str);
}
} catch (IOException e) {
e.printStackTrace();
}
}
}
}
客户端:
package com.guchao.chat;
import java.io.BufferedReader;
import java.io.DataInputStream;
import java.io.DataOutputStream;
import java.io.IOException;
import java.io.InputStreamReader;
import java.net.Socket;
import java.net.UnknownHostException;
public class TCPClient {
public static void main(String[] args) throws UnknownHostException, IOException{
new TCPClient().go();
}
public void go() {
try {
Socket s = new Socket("127.0.0.1",8888);
// 启动读线程,从socket中读取信息
RecvThread recv = new RecvThread(s);
new Thread(recv).start();
// 启动写线程,写入信息到socket中
SendThread send = new SendThread(s);
new Thread(send).start();
} catch (UnknownHostException e) {
e.printStackTrace();
} catch (IOException e) {
e.printStackTrace();
}
}
class RecvThread implements Runnable{
private DataInputStream dis = null;
public RecvThread(Socket s){
try {
dis = new DataInputStream(s.getInputStream());
} catch (IOException e) {
e.printStackTrace();
}
}
@Override
public void run() {
String str = "";
while(true){
try {
//从socket中读取信息
str = dis.readUTF();
if("bye".equals(str))
break;
System.out.println("received message:"+str);
} catch (IOException e) {
e.printStackTrace();
}
}
}
}
class SendThread implements Runnable{
private DataOutputStream dos;
public SendThread(Socket s){
try {
dos = new DataOutputStream(s.getOutputStream());
} catch (IOException e) {
e.printStackTrace();
}
}
@Override
public void run() {
String str = "";
while(true){
System.out.println("input message:");
BufferedReader br = new BufferedReader(new InputStreamReader(System.in));
try {
str = br.readLine();
// 写入信息到socket中
dos.writeUTF(str);
if("bye".equals(str))
break;
} catch (IOException e) {
e.printStackTrace();
}
}
}
}
}
分享到:
相关推荐
TCP/IP Socket 网络编程 TCP/IP Socket 网络编程是计算机网络领域中一个非常重要的主题,涉及到计算机网络的通信协议、网络架构、Socket 编程接口等方面的知识。 Internet 与 TCP/IP 协议: Internet 的历史可以...
Java是当前最流行的网络编程语言,对实现TCP协议进行了封装,为实现聊天系统的雏形提供了便利。 一、TCP协议介绍 TCP是一种面向连接的协议,提供了可靠性的和端到端的服务,为用户提供了可靠性的和端到端的服务。...
在JavaSE中,Socket编程是实现网络通信的基础,它提供了客户端和服务器端之间进行数据交换的接口。在这个项目“[JavaSE]使用Socket做的点对点聊天雏形”中,我们利用了Java的Swing库来创建用户界面,并通过Socket和...
1. **Windows Socket编程基础** - Winsock是Windows平台上的网络编程接口,它遵循Berkeley Sockets API标准,使得开发者能够编写跨平台的网络应用。 - Winsock库提供了套接字API,用于创建、连接、发送和接收数据...
本PPT课件主要讲述了TCPIP Socket网络编程的基本概念、 historical background、TCP/IP协议的发展过程、网络模型、Socket编程接口等内容。下面是对该PPT课件的详细知识点总结: 一、Internet和TCP/IP协议的历史背景...
本文将围绕“在线系聊天统雏形”这一主题,深入探讨其核心技术——Socket编程和多线程,并结合提供的压缩包文件"Chat1.3"进行解析。 首先,Socket编程是网络通信的基础,它提供了在网络中两台计算机之间建立连接并...
在这个系统中,主要涉及了Java的Socket编程、多线程以及数据序列化等核心技术,这些都是构建实时聊天应用不可或缺的部分。 1. **Java Socket编程**:在Java中,Socket是实现网络通信的基本工具,它提供了客户端与...
- **网络流**:Socket编程中的ServerSocket和Socket类提供了网络流的处理,如InputStream和OutputStream的子类DataInputStream和DataOutputStream,它们方便了在网络中进行结构化数据的传输。 - **缓冲流**:...
Java提供了Socket编程接口,使得我们可以创建基于TCP/IP协议的客户端和服务端程序,这是构建在线聊天系统的基础。Socket允许两个应用程序通过网络进行数据传输,就像聊天系统中的用户发送和接收消息。 其次,...
本项目是一个基于C#实现的聊天组件程序,它为开发者提供了一个基础的聊天室雏形,适用于学习和实践C#编程技能。在这个简单的聊天程序中,你将能够了解到C#中的网络通信、多线程、UI设计等多个关键知识点。 首先,C#...
在线聊天服务端与客户端之间的通信主要依赖于Java的Socket编程。Socket是TCP/IP协议族的一部分,它提供了两台计算机之间网络通信的基本机制。服务端通常会创建一个ServerSocket监听特定端口,等待客户端的连接请求...
客户端与服务器之间的消息传递是通过发送和接收数据包实现的,这涉及到网络编程的基本概念,如套接字(socket)、连接建立与断开、数据封包和解包等。 7. **多线程编程**:服务器端通常需要处理多个客户端的请求,...
- **UNIX的诞生**:1969年,肯·汤普逊开始在一台废弃的PDP-7机器上开发一个新的操作系统,这就是Unix的雏形。1970年,Unix第一版发布,采用C语言编写,这标志着Unix作为现代操作系统的开端。 - **1979—UNIX第七版*...
它提供了Socket编程接口,用于实现客户端和服务器之间的通信。 2. **网络编程**:为了实现网络版五子棋,开发者必须理解TCP/IP协议和套接字编程。玩家之间需要通过网络交换棋盘状态和聊天消息,这涉及到了数据的...
IPv6原理\应用与实践 ICMPV6\radvd\dhcpv6\PPPOEV6 IPv6的基本概念 IPv6在Linux操作系统下的实现 IPv6的实验 IPv6的过渡技术介绍 ...IPv6在Linux平台下socket编程应该注意的问题 实现简易版TGW支持IPv6雏形demo
1. **Socket编程**:Java中的`java.net.DatagramSocket`类是实现UDP通信的基础。它代表了一个UDP套接字,可以用于发送和接收数据报。创建`DatagramSocket`实例后,我们可以通过`send()`方法发送数据报,通过`receive...
1. **Java网络编程基础**:在实现网络消息过滤器前,我们需要掌握Java的Socket编程。Socket是Java提供的一种网络通信接口,它允许应用程序通过TCP/IP协议与网络上的其他进程进行通信。源码中可能会包含ServerSocket...
在本项目中,我们探讨的是如何使用VC++(Visual C++)编程语言构建一个基本的HTTP服务器雏形。HTTP(超文本传输协议)是互联网上应用最广泛的一种网络协议,用于从万维网服务器传输超文本到本地浏览器。通过理解和...