基于socket简易聊天程序
socket编程聊天室基本流程

socket编程聊天室基本流程一、引言Socket编程是一种用于网络通信的编程技术。
它允许程序员创建客户端和服务器应用程序,这些应用程序可以在不同的计算机上运行并通过Internet或局域网相互通信。
在本文中,我们将介绍Socket编程聊天室的基本流程。
二、Socket编程概述Socket编程是一种基于TCP/IP协议的网络编程技术。
它使用套接字(socket)来实现网络通信。
套接字是一种抽象概念,它表示一个网络连接点,可以用来发送和接收数据。
在Socket编程中,客户端和服务器之间建立一个连接,然后通过这个连接进行数据传输。
客户端向服务器发送请求,并等待服务器响应。
服务器接收请求并处理它,并将响应发送回客户端。
三、Socket编程聊天室基本流程1. 创建服务器程序首先,我们需要创建一个服务器程序来监听客户端连接请求。
在Python中,可以使用socket模块来创建套接字对象,并使用bind()方法将其绑定到指定的IP地址和端口号上。
2. 创建客户端程序然后,我们需要创建一个客户端程序来连接到服务器。
同样地,在Python中可以使用socket模块来创建套接字对象,并使用connect()方法连接到指定的IP地址和端口号上。
3. 实现消息传输一旦客户端和服务器之间建立了连接,它们就可以开始进行消息传输。
在Socket编程中,可以使用send()方法将数据发送到对方,使用recv()方法从对方接收数据。
4. 实现聊天室功能为了实现聊天室功能,我们需要让多个客户端能够同时连接到服务器,并且能够相互通信。
为此,我们可以使用多线程或异步编程技术来实现。
在多线程模式下,每个客户端连接都会被分配一个独立的线程来处理。
这个线程负责接收客户端发送的消息,并将其转发给其他客户端。
在异步编程模式下,我们可以使用协程或回调函数来处理消息传输。
当有新的消息到达时,就会触发相应的回调函数进行处理。
5. 实现用户管理为了实现用户管理功能,我们需要让每个客户端都能够注册一个唯一的用户名,并且能够查看当前在线的用户列表。
基于Web socket技术的聊天系统开发

基于Web socket技术的聊天系统开发随着互联网的发展和智能手机的普及,人与人之间的沟通方式也发生了巨大的变化。
在过去,我们通过电话、短信、邮件等方式进行交流,而现在,我们更多地借助于各种社交软件来实现即时通讯。
而Web技术的发展也为聊天系统的开发提供了更多的可能性,其中Web socket技术就是其中一个重要的技术之一。
本文将针对基于Web socket技术的聊天系统开发进行详细的介绍和分析。
一、Web socket技术的基本概念和特点Web socket是HTML5提出的一种新协议,它实现了浏览器和服务器之间全双工通信。
在传统的HTTP协议中,客户端必须主动向服务器发起请求,然后服务器才能响应客户端的请求。
这种单向的通信机制并不适合于一些需要实时交互的场景,比如聊天系统。
Web socket技术通过在客户端和服务器之间建立一个持久连接来实现实时通信。
这意味着一旦建立了连接,客户端和服务器就可以直接进行双向的通信,而不需要再通过传统的HTTP请求响应的方式来完成。
这种全双工的通信方式极大地方便了实时交互的实现,可以大大提升用户体验。
1. 实时性强:Web socket技术能够实现实时的双向通信,适合于需要及时响应的场景,在聊天系统中尤为重要。
2. 低延迟:由于建立了持久连接,可以减少建立连接和断开连接的开销,从而降低了通信的延迟。
3. 节省带宽:相比传统的HTTP请求响应方式,Web socket技术的头部信息更小,可以节省带宽和服务器资源。
Web socket技术具有更好的实时性、更低的延迟和更高的效率,非常适合于开发聊天系统这类实时通信的应用。
在实际开发中,基于Web socket技术的聊天系统可以采用前后端分离的架构,前端负责与用户交互和展示数据,后端负责处理业务逻辑和与数据库交互。
下面是基于Web socket技术的聊天系统实现的具体方案:1. 前端实现:前端可以选择使用现有的Web socket相关库,比如Socket.io、SockJS等来实现与服务器的通信。
unity3d游戏开发之实现基于Socket通讯的公共聊天室

由于这段时间比较忙,所以也很久没发布过新的教程,这几天刚好要为一个项目写服务端程序,所以顺便也在Unity3d里面实现了一个简单的客户端,多个客户端一同使用就是一个简单的公共聊天室了。
服务端为一个控制台程序使用C#实现,当然,在Unity3d中也相应地使用了C#语言实现客户端,服务端和客户端能实现消息的互通,当服务端接收到某客户端发送过来的消息时将会对客户端列表成员进行广播,这是公共聊天室的最基本的形式。
Socket通讯是网络游戏最为基础的知识,因此这个实例能向有志投身于网游行业的初学者提供指导意义。
这篇文章来自ing System;ing ;ing ;ing TestServer5.{6. class Program7. {8. .\n");9.10. .\n");11. }12. }13. }14.}ing System;ing ;ing ;ing ;ing TestServer6.{7. class ChatClient8. {9. public static Hashtable ALLClients = new Hashtable();eginRead(data, 0, ReceiveMessage, null);10. }11.12. ;13.14. ;15. }16. }17.18. endMessage(message + ;19. }20. }21.22. }23.}Unity3d客户端的代码:ing UnityEngine;ing ;3.ing System;ing ;ing ;ing class ClientHandler : MonoBehaviour8.{9. const int portNo = 500;10. private TcpClient _client;11. byte[] data;12.13. // Use this for initialization14. void Start ()15. {16.17. }18.19. // Update is called once per frame20. void Update ()21. {22.23. }24.25. public string nickName = "";26. public string message = "";27. public string sendMsg = "";28.29. void OnGUI()30. {31. nickName = (new Rect(10, 10, 100, 20), nickName);32. message = (new Rect(10, 40, 300, 200), message);33. sendMsg = (new Rect(10, 250, 210, 20), sendMsg);34.35. if(new Rect(120, 10, 80, 20), "Connect"))36. {37. //("hello");38.39. = new TcpClient();40. "", portNo);41.42. data = new byte[ //SendMessage;43. SendMessage(nickName);44.45. 0, ReceiveMessage, null);46. };47.48. if(new Rect(230, 250, 80, 20), "Send"))49. {50. SendMessage(sendMsg);51. sendMsg = "";52. };53. }54.55. public void SendMessage(string message)56. {57. try58. {workStream ns = byte[] data= (data, 0, ;60. ();61. }62. catch (Exception ex)63. {64. //());65. }66. }67.68. public void ReceiveMessage(IAsyncResult ar)69. {70. try71. {72. int bytesRead;73.74. bytesRead = if (bytesRead < 1)75. {76. return;77. }78. else79. {80.81. 0, bytesRead));82.83. message += 0, bytesRead);84. }85.86. 0, ReceiveMessage, null);87.88.89. }90. catch (Exception ex)91. {92.93. }94. }95.}。
C#基于socket的聊天工具与其源码

C#基于socket的聊天工具与其源码本例为家猫本人原作,做此工具时刚从学校毕业,那会比较爱学习,所以此工具代码有点点乱,此工具本是基于局域网的聊天工具,无需建立服务端,直接通过协议同步网内用户后来扩展了外网功能,后面会讲到主要是用于公司内部交流用,集成了涂鸦,表情,截图等简单功能当启动nettalk工具后,可以在菜单个人设置中简单地设置下名称和分组下面是涂鸦效果图:功能都比较简单,,可以用来学习,,用到的知识点还是很广的局域网聊天很简单,服务端都不用启用,直接每个人启动客户端即可下面来说说怎么部署到外网:首先得有一台外网能访问的机器,一般家庭网络的做法是通过路由器映射一个端口到您当做服务器的IP上,我默认用的端口是:60000你可以改为你需要的端口,如果改端口得到server端的app.config中的配置改为你的端口,port为服务端采用的端口server就是您的外网IP,我这里用的是花生壳域名,因为我没有静态IP1<?xml version="1.0" encoding="utf-8" ?>2<configuration>3<configSections>4</configSections>5<connectionStrings>6</connectionStrings>7<appSettings>8<!-- 是否自动启动并开启服务器-->9<add key="AUTOSTART" value="false"/>10<!--是否对本地用户监听-->11<add key="LISTENLOCAL" value="false"/>12<!--是否为二级服务器-->13<add key="LEVELSERVER" value="false"/>14<!--如果为二级服务器此地址才会有效,为主服务器的地址-->15<add key="SERVER" value=""/>16<!--如果为主服务器,此项为主服务器的监听端口,,如果为二级服务器,此端口为远程主服务器的端口,与SERVER项一起使用-->17<add key="PORT" value="60000"/>18</appSettings>19</configuration>配置好服务端后启动程序:点控制菜单中的启动服务即可成功启动后,,其它客户端就可以登录此服务端了外网需要注册用户,,在服务端工具菜单有注册用户。
MFC实现简单网络聊天程序

MFC实现简单网络聊天程序MFC(Microsoft Foundation Classes)是微软公司提供的一个应用程序框架,用于开发Windows系统上的图形用户界面程序。
在此基础上,我们可以利用MFC来实现简单的网络聊天程序。
首先,我们需要创建一个MFC应用程序项目。
使用Visual Studio打开,选择MFC应用程序向导,选择对话框风格。
然后,设置对话框的布局,包括聊天消息显示框、消息输入框、发送按钮等控件。
接下来,我们需要使用Socket编程来实现网络通信功能。
MFC提供了CSocket类,我们可以使用它来处理数据的发送和接收。
在对话框类中添加成员变量m_socket,类型为CSocket。
在OnInitDialog函数中,我们需要创建Socket,并进行连接。
可以通过使用Create函数创建CSocket对象,并调用Connect函数来连接指定的地址和端口号。
例如,可以连接到本地主机上的一些端口,这样就可以进行本地测试。
然后,我们需要添加事件处理函数来处理发送和接收消息。
当发送按钮被点击时,可以通过调用Socket对象的Send函数将消息发送给服务器。
可以使用CString类来处理字符串数据。
当接收到消息时,可以通过调用Socket对象的Receive函数将消息接收到的缓冲区中。
为了提供实时地聊天消息显示功能,我们需要使用SetWindowText函数将数据显示到聊天消息显示框中。
当接收到消息时,可以将消息显示在聊天消息显示框中,同时可以使用UpdateData函数实时更新界面。
在程序结束时,我们需要断开连接并销毁Socket对象。
在析构函数中,可以调用Shutdown函数来关闭连接,然后销毁Socket对象。
除了基本的发送和接收消息功能,我们还可以添加一些其他的功能,比如可以使用菜单栏来选择连接和断开服务器,可以添加登录和注册功能等。
这些可以根据实际需求进行扩展。
总结起来,通过使用MFC应用程序框架和Socket编程,我们可以实现简单的网络聊天程序。
qtcpsocket案例

qtcpsocket案例QTcpSocket是Qt框架提供的用于进行TCP通信的类。
它提供了一系列的接口函数,可以实现TCP客户端和服务器端的功能。
下面是一个使用QTcpSocket的案例。
假设我们有一个简单的网络聊天室系统,实现客户端之间的聊天功能。
首先我们需要创建一个客户端,连接到服务器。
客户端发送消息给服务器,当服务器接收到消息后,将消息广播给所有连接到服务器的客户端。
首先创建一个Qt的控制台应用程序,包括头文件`QTcpSocket`。
在主函数中创建一个客户端类`ChatClient`,并调用其成员函数`start`启动客户端。
```cpp#include <QCoreApplication>#include <QTcpSocket>class ChatClient : public QObjectQ_OBJECTpublic:ChatClientsocket = new QTcpSocket(this);connect(socket, &QTcpSocket::connected, this,&ChatClient::onConnected);connect(socket, &QTcpSocket::readyRead, this,&ChatClient::onReadyRead);}void startsocket->connectToHost("localhost", 1234);qDebug( << "Connecting to server...";}private slots:void onConnectedqDebug( << "Connected to server";socket->write("Hello server");}void onReadyReadQString message = QString::fromUtf8(socket->readAll();qDebug( << "Received message:" << message;}private:QTcpSocket* socket;};int main(int argc, char *argv[])QCoreApplication a(argc, argv);ChatClient client;client.start(;return a.exec(;```上面的代码中,我们首先在构造函数中创建了一个`QTcpSocket`对象,并连接了`connected`和`readyRead`信号,分别与`onConnected`和`onReadyRead`槽函数绑定。
湖南大学计算机网络实验-聊天实验

一,实验说明所用语言及工具:java,myeclipse。
二,实验内容基于网络socket编程,我做的是用socket实现一个简易的多人聊天室,可以同时多个人聊天。
三,实验原理网际协议(Internet Protocol, IP)是一种用于互联网的网络协议。
它可广泛用于大多数计算机操作系统上,也可用于大多数局域网L A N(比如办公室小型网络)和广域网WAN(比如说互联网)。
两个上层协议(TCP和UDP)依赖IP协议进行数据通信。
通过TCP和UDP协议建立网络应用程序,需要使用java JDK提供套接口编程技术。
Java的JDK提供了很多编程接口,比如在客户端使用Socket client = new Socket(ip,port);即可与IP是ip的服务器的port端口进行连接,同时在服务器端,ServerSocket server = new ServerSocket(port);开启端口为port来监听是否有客户端连接。
连接成功后可以在客户端和服务器端进行数据的交换。
在该实验中使用字节输入输出流,为了增加传输效率,用套一个缓冲流来处理数据的传输。
如在接收方:InputStream in = client.getInputStream();BufferedReader reader= new BufferedReader(new InputStreamReader(in));本次实验中我的基本模式可以描述为以下一个过程:四,实验过程1,建立一个java工程,在工程下新建client和server包,和一个用户界面的GUI包。
2,编写服务端ServerSocket server = new ServerSocket(8888);将本机的8888端口作为监听客户端连接的端口。
等待连接:while(true){Socket client = server.accept();......}用while循环等待客户端连接进来。
SpringBoot实战之netty-socketio实现简单聊天室(给指定用户推送消息)

SpringBoot实战之netty-socketio实现简单聊天室(给指定⽤户推送消息)⽹上好多例⼦都是群发的,本⽂实现⼀对⼀的发送,给指定客户端进⾏消息推送1、本⽂使⽤到netty-socketio开源库,以及MySQL,所以⾸先在pom.xml中添加相应的依赖库<dependency><groupId>com.corundumstudio.socketio</groupId><artifactId>netty-socketio</artifactId><version>1.7.11</version></dependency><dependency><groupId>org.springframework.boot</groupId><artifactId>spring-boot-starter-data-jpa</artifactId></dependency><dependency><groupId>mysql</groupId><artifactId>mysql-connector-java</artifactId></dependency>2、修改application.properties, 添加端⼝及主机数据库连接等相关配置,wss.server.port=8081wss.server.host=localhostspring.datasource.url = jdbc:mysql://127.0.0.1:3306/springlearnername = rootspring.datasource.password = rootspring.datasource.driverClassName = com.mysql.jdbc.Driver# Specify the DBMSspring.jpa.database = MYSQL# Show or not log for each sql queryspring.jpa.show-sql = true# Hibernate ddl auto (create, create-drop, update)spring.jpa.hibernate.ddl-auto = update# Naming strategyspring.jpa.hibernate.naming-strategy = org.hibernate.cfg.ImprovedNamingStrategy# stripped before adding them to the entity manager)spring.jpa.properties.hibernate.dialect = org.hibernate.dialect.MySQL5Dialect3、修改Application⽂件,添加nettysocket的相关配置信息package com.xiaofangtech.sunt;import org.springframework.beans.factory.annotation.Value;import org.springframework.boot.SpringApplication;import org.springframework.boot.autoconfigure.SpringBootApplication;import org.springframework.context.annotation.Bean;import com.corundumstudio.socketio.AuthorizationListener;import com.corundumstudio.socketio.Configuration;import com.corundumstudio.socketio.HandshakeData;import com.corundumstudio.socketio.SocketIOServer;import com.corundumstudio.socketio.annotation.SpringAnnotationScanner;@SpringBootApplicationpublic class NettySocketSpringApplication {@Value("${wss.server.host}")private String host;@Value("${wss.server.port}")private Integer port;@Beanpublic SocketIOServer socketIOServer(){Configuration config = new Configuration();config.setHostname(host);config.setPort(port);//该处可以⽤来进⾏⾝份验证config.setAuthorizationListener(new AuthorizationListener() {@Overridepublic boolean isAuthorized(HandshakeData data) {//http://localhost:8081?username=test&password=test//例如果使⽤上⾯的链接进⾏connect,可以使⽤如下代码获取⽤户密码信息,本⽂不做⾝份验证// String username = data.getSingleUrlParam("username");// String password = data.getSingleUrlParam("password");return true;}});final SocketIOServer server = new SocketIOServer(config);return server;}@Beanpublic SpringAnnotationScanner springAnnotationScanner(SocketIOServer socketServer) {return new SpringAnnotationScanner(socketServer);}public static void main(String[] args) {SpringApplication.run(NettySocketSpringApplication.class, args);}}4、添加消息结构类MessageInfo.javapackage com.xiaofangtech.sunt.message;public class MessageInfo {//源客户端idprivate String sourceClientId;//⽬标客户端idprivate String targetClientId;//消息类型private String msgType;//消息内容private String msgContent;public String getSourceClientId() {return sourceClientId;}public void setSourceClientId(String sourceClientId) {this.sourceClientId = sourceClientId;}public String getTargetClientId() {return targetClientId;}public void setTargetClientId(String targetClientId) {this.targetClientId = targetClientId;}public String getMsgType() {return msgType;}public void setMsgType(String msgType) {this.msgType = msgType;}public String getMsgContent() {return msgContent;}public void setMsgContent(String msgContent) {this.msgContent = msgContent;}}5、添加客户端信息,⽤来存放客户端的sessionidpackage com.xiaofangtech.sunt.bean;import java.util.Date;import javax.persistence.Entity;import javax.persistence.Id;import javax.persistence.Table;import javax.validation.constraints.NotNull;@Entity@Table(name="t_clientinfo")public class ClientInfo {@Id@NotNullprivate String clientid;private Short connected;private Long mostsignbits;private Long leastsignbits;private Date lastconnecteddate;public String getClientid() {return clientid;}public void setClientid(String clientid) {this.clientid = clientid;}public Short getConnected() {return connected;}public void setConnected(Short connected) {this.connected = connected;}public Long getMostsignbits() {return mostsignbits;}public void setMostsignbits(Long mostsignbits) {this.mostsignbits = mostsignbits;}public Long getLeastsignbits() {return leastsignbits;}public void setLeastsignbits(Long leastsignbits) {this.leastsignbits = leastsignbits;}public Date getLastconnecteddate() {return lastconnecteddate;}public void setLastconnecteddate(Date lastconnecteddate) {stconnecteddate = lastconnecteddate;}}6、添加查询数据库接⼝ClientInfoRepository.javapackage com.xiaofangtech.sunt.repository;import org.springframework.data.repository.CrudRepository;import com.xiaofangtech.sunt.bean.ClientInfo;public interface ClientInfoRepository extends CrudRepository<ClientInfo, String>{ ClientInfo findClientByclientid(String clientId);}7、添加消息处理类MessageEventHandler.Javapackage com.xiaofangtech.sunt.message;import java.util.Date;import java.util.UUID;import org.springframework.beans.factory.annotation.Autowired;import ponent;import com.corundumstudio.socketio.AckRequest;import com.corundumstudio.socketio.SocketIOClient;import com.corundumstudio.socketio.SocketIOServer;import com.corundumstudio.socketio.annotation.OnConnect;import com.corundumstudio.socketio.annotation.OnDisconnect;import com.corundumstudio.socketio.annotation.OnEvent;import com.xiaofangtech.sunt.bean.ClientInfo;import com.xiaofangtech.sunt.repository.ClientInfoRepository;@Componentpublic class MessageEventHandler{private final SocketIOServer server;@Autowiredprivate ClientInfoRepository clientInfoRepository;@Autowiredpublic MessageEventHandler(SocketIOServer server){this.server = server;}//添加connect事件,当客户端发起连接时调⽤,本⽂中将clientid与sessionid存⼊数据库//⽅便后⾯发送消息时查找到对应的⽬标client,@OnConnectpublic void onConnect(SocketIOClient client){String clientId = client.getHandshakeData().getSingleUrlParam("clientid");ClientInfo clientInfo = clientInfoRepository.findClientByclientid(clientId);if (clientInfo != null){Date nowTime = new Date(System.currentTimeMillis());clientInfo.setConnected((short)1);clientInfo.setMostsignbits(client.getSessionId().getMostSignificantBits());clientInfo.setLeastsignbits(client.getSessionId().getLeastSignificantBits());clientInfo.setLastconnecteddate(nowTime);clientInfoRepository.save(clientInfo);}}//添加@OnDisconnect事件,客户端断开连接时调⽤,刷新客户端信息@OnDisconnectpublic void onDisconnect(SocketIOClient client){String clientId = client.getHandshakeData().getSingleUrlParam("clientid");ClientInfo clientInfo = clientInfoRepository.findClientByclientid(clientId);if (clientInfo != null){clientInfo.setConnected((short)0);clientInfo.setMostsignbits(null);clientInfo.setLeastsignbits(null);clientInfoRepository.save(clientInfo);}}//消息接收⼊⼝,当接收到消息后,查找发送⽬标客户端,并且向该客户端发送消息,且给⾃⼰发送消息 @OnEvent(value = "messageevent")public void onEvent(SocketIOClient client, AckRequest request, MessageInfo data){String targetClientId = data.getTargetClientId();ClientInfo clientInfo = clientInfoRepository.findClientByclientid(targetClientId);if (clientInfo != null && clientInfo.getConnected() != 0){UUID uuid = new UUID(clientInfo.getMostsignbits(), clientInfo.getLeastsignbits());System.out.println(uuid.toString());MessageInfo sendData = new MessageInfo();sendData.setSourceClientId(data.getSourceClientId());sendData.setTargetClientId(data.getTargetClientId());sendData.setMsgType("chat");sendData.setMsgContent(data.getMsgContent());client.sendEvent("messageevent", sendData);server.getClient(uuid).sendEvent("messageevent", sendData);}}}8、添加ServerRunner.javapackage com.xiaofangtech.sunt.message;import org.springframework.beans.factory.annotation.Autowired;import mandLineRunner;import ponent;import com.corundumstudio.socketio.SocketIOServer;@Componentpublic class ServerRunner implements CommandLineRunner {private final SocketIOServer server;@Autowiredpublic ServerRunner(SocketIOServer server) {this.server = server;}@Overridepublic void run(String... args) throws Exception {server.start();}}9、⼯程结构10、运⾏测试1)添加基础数据,数据库中预置3个客户端testclient1,testclient2,testclient32) 创建客户端⽂件index.html,index2.html,index3.html分别代表testclient1 testclient2 testclient3三个⽤户其中clientid为发送者id, targetclientid为⽬标⽅id,本⽂简单的将发送⽅和接收⽅写死在html⽂件中使⽤以下代码进⾏连接io.connect('http://localhost:8081?clientid='+clientid);index.html ⽂件内容如下<!DOCTYPE html><html><head><meta charset="utf-8" /><title>Demo Chat</title><link href="bootstrap.css" rel="external nofollow" rel="stylesheet"><style>body {padding:20px;}#console {height: 400px;overflow: auto;}.username-msg {color:orange;}.connect-msg {color:green;}.disconnect-msg {color:red;}.send-msg {color:#888}</style><script src="js/socket.io/socket.io.js"></script><script src="js/moment.min.js"></script><script src="/jquery-1.10.1.min.js"></script><script>var clientid = 'testclient1';var targetClientId= 'testclient2';var socket = io.connect('http://localhost:8081?clientid='+clientid);socket.on('connect', function() {output('<span class="connect-msg">Client has connected to the server!</span>');});socket.on('messageevent', function(data) {output('<span class="username-msg">' + data.sourceClientId + ':</span> ' + data.msgContent);});socket.on('disconnect', function() {output('<span class="disconnect-msg">The client has disconnected!</span>');});function sendDisconnect() {socket.disconnect();}function sendMessage() {var message = $('#msg').val();$('#msg').val('');var jsonObject = {sourceClientId: clientid,targetClientId: targetClientId,msgType: 'chat',msgContent: message};socket.emit('messageevent', jsonObject);}function output(message) {var currentTime = "<span class='time'>" + moment().format('HH:mm:ss.SSS') + "</span>";var element = $("<div>" + currentTime + " " + message + "</div>");$('#console').prepend(element);}$(document).keydown(function(e){if(e.keyCode == 13) {$('#send').click();}});</script></head><body><h1>Netty-socketio Demo Chat</h1><br/><div id="console" class="well"></div><form class="well form-inline" onsubmit="return false;"><input id="msg" class="input-xlarge" type="text" placeholder="Type something..."/><button type="button" onClick="sendMessage()" class="btn" id="send">Send</button><button type="button" onClick="sendDisconnect()" class="btn">Disconnect</button></form></body></html>3、本例测试时testclient1 发送消息给 testclient2testclient2 发送消息给 testclient1testclient3发送消息给testclient1运⾏结果如下以上就是本⽂的全部内容,希望对⼤家的学习有所帮助,也希望⼤家多多⽀持。
- 1、下载文档前请自行甄别文档内容的完整性,平台不提供额外的编辑、内容补充、找答案等附加服务。
- 2、"仅部分预览"的文档,不可在线预览部分如存在完整性等问题,可反馈申请退款(可完整预览的文档不适用该条件!)。
- 3、如文档侵犯您的权益,请联系客服反馈,我们会尽快为您处理(人工客服工作时间:9:00-18:30)。
简单的socket程序
2010-01-13 22:18
虽然很简单,但还是调试了很长时间。
本科时候接触过socket——那个帅帅的刘
老师的课,现在重新再捡起来。
程序中专门建立一个FunThread线程用来接收数据,实现双向通信,也可以连续发送、连续接收。
代码贴上来,如果还能保留VA View那样的颜色区别就好看
了,但是试了好几遍都不行
server:
#include <WINSOCK2.H>
#include <stdio.h>
#define PORT 6000 //服务器端口
#define MSGSIZE 1024 //收发缓冲区的大小
#pragma comment(lib, "ws2_32.lib") //链接静态库
DWORD WINAPI FunThread(LPVOID); //创建一个线程,专门用来接收数据
SOCKET sClient; //连接所用套节字
SOCKET sListen; //监听套接字
SOCKADDR_IN client; //保存客户的地址信息
int iaddrSize = sizeof(SOCKADDR_IN);
int main()
{
WSADATA wsaData;
SOCKADDR_IN local;
char s_Message[MSGSIZE]; //收发缓冲区
WSAStartup(0x0202, &wsaData); //Initialize Windows socket library
sListen = socket(AF_INET, SOCK_STREAM, IPPROTO_TCP);//创建服务器监听套节字。
TCP协议
local.sin_family = AF_INET; //AF_INET指明使用TCP/IP协议族
local.sin_port = htons(PORT);//指明连接服务器的端口号
local.sin_addr.s_addr = htonl(INADDR_ANY);//自动获取本机地址
bind(sListen, (struct sockaddr *)&local, sizeof(SOCKADDR_IN));//地址绑定到套接字
listen(sListen, 1);//开始监听
sClient = accept(sListen, (struct sockaddr *)&client, &iaddrSize);//建立连接
printf("Accepte client:%s:%d\n", inet_ntoa(client.sin_addr),
ntohs(client.sin_port));
HANDLE hThread=CreateThread(NULL,0,FunThread,0,0,0);//创建接收线程CloseHandle(hThread);
while (TRUE)
{
printf("Server Send:");
//从键盘输入
gets(s_Message);
//发送数据
send(sClient, s_Message, strlen(s_Message), 0);
}
return 0;
}
DWORD WINAPI FunThread(LPVOID)
{
char c_Message[MSGSIZE]; //收发缓冲区
int ret; //接收字节的个数
while (TRUE)
{
ret = recv(sClient, c_Message, MSGSIZE, 0);//接收数据
if(ret==SOCKET_ERROR)
{
printf("\nclient is closed!");
sClient = accept(sListen, (struct sockaddr *)&client, &iaddrSize);//重新开始监听
printf("\nAccepte new client:%s:%d", inet_ntoa(client.sin_addr), ntohs(client.sin_port));
memset(c_Message,0,1024);//将原来的client message归零
continue;
}
c_Message[ret] = '\0';
printf("\nReceived: %s\n", c_Message);
}
return 0;
}
client:
#include <WINSOCK2.H>
#include <stdio.h>
#define SERVER_ADDRESS "127.0.0.1" //服务器端IP地址
#define PORT 6000
#define MSGSIZE 1024
#pragma comment(lib, "ws2_32.lib")
DWORD WINAPI FunThread(LPVOID);
SOCKET sClient;
SOCKADDR_IN server;
int main()
{
WSADATA wsaData;
char c_Message[MSGSIZE];
WSAStartup(0x0202, &wsaData);
sClient = socket(AF_INET, SOCK_STREAM, IPPROTO_TCP);
memset(&server, 0, sizeof(SOCKADDR_IN)); //先将保存地址的server置为全0
server.sin_family = PF_INET; //声明地址格式是TCP/IP地址格式
server.sin_port = htons(PORT); //指明连接服务器的端口号
server.sin_addr.s_addr = inet_addr(SERVER_ADDRESS); //指明连接服务器的IP地址
connect(sClient, (struct sockaddr *)&server, sizeof(SOCKADDR_IN)); //连到刚才指明的服务器上
HANDLE hThread=CreateThread(NULL,0,FunThread,0,0,0);
CloseHandle(hThread);
while (TRUE)
{
printf("Client Send:");
gets(c_Message);
send(sClient, c_Message, strlen(c_Message), 0);
if(!strcmp(c_Message,"exit"))//client自身退出
exit(1);
}
// 释放连接和进行结束工作
closesocket(sClient);
WSACleanup();
return 0;
}
DWORD WINAPI FunThread(LPVOID)
{
char s_Message[MSGSIZE];
int ret;
while (TRUE)
{
ret = recv(sClient, s_Message, MSGSIZE, 0);
if(ret==SOCKET_ERROR)
{
printf("\nServer is closed!\n");
exit(1);
}
s_Message[ret] = '\0';
printf("\nReceived: %s\n", s_Message);
if(!strcmp(s_Message,"exit"))//server让client退出
exit(1);
}
return 0;
}
程序在VC++ 6.0环境下编译通过。
先运行server端,再运行client,链接建立:
client和server可进行双通信,可连续发送、接收;client可自行退出,也可由server强制退出,发送exit命令即可:
client退出后,server重新建立监听,有新的client运行时,再次建立新的连接:
注意:client的端口号是随机的。
服务器关闭时,client自动退出:。