socket编程TCP实现简单聊天功能
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. 实现用户管理为了实现用户管理功能,我们需要让每个客户端都能够注册一个唯一的用户名,并且能够查看当前在线的用户列表。
socket实例C语言:一个简单的聊天程序
socket实例C语⾔:⼀个简单的聊天程序我们⽼师让写⼀个简单的聊天软件,并且实现不同机⼦之间的通信,我⽤的是SOCKET编程。
不废话多说了,先附上代码:服务器端server.c#include <stdio.h>#include <stdlib.h>#include <string.h>#include <errno.h>#include <sys/socket.h>#include <arpa/inet.h>#include <netinet/in.h>#include <sys/types.h>#include <unistd.h>#include <sys/time.h>#define BUFLEN 1024#define PORT 6666#define LISTNUM 20int main(){int sockfd, newfd;struct sockaddr_in s_addr, c_addr;char buf[BUFLEN];socklen_t len;unsigned int port, listnum;fd_set rfds;struct timeval tv;int retval,maxfd;/*建⽴socket*/if((sockfd = socket(PF_INET, SOCK_STREAM, 0)) == -1){perror("socket");exit(errno);}elseprintf("socket create success!\n");memset(&s_addr,0,sizeof(s_addr));s_addr.sin_family = AF_INET;s_addr.sin_port = htons(PORT);s_addr.sin_addr.s_addr = htons(INADDR_ANY);/*把地址和端⼝帮定到套接字上*/if((bind(sockfd, (struct sockaddr*) &s_addr,sizeof(struct sockaddr))) == -1){perror("bind");exit(errno);}elseprintf("bind success!\n");/*侦听本地端⼝*/if(listen(sockfd,listnum) == -1){perror("listen");exit(errno);}elseprintf("the server is listening!\n");while(1){printf("*****************聊天开始***************\n");len = sizeof(struct sockaddr);if((newfd = accept(sockfd,(struct sockaddr*) &c_addr, &len)) == -1){perror("accept");exit(errno);}elseprintf("正在与您聊天的客户端是:%s: %d\n",inet_ntoa(c_addr.sin_addr),ntohs(c_addr.sin_port));while(1){FD_ZERO(&rfds);FD_SET(0, &rfds);maxfd = 0;FD_SET(newfd, &rfds);/*找出⽂件描述符集合中最⼤的⽂件描述符*/if(maxfd < newfd)maxfd = newfd;/*设置超时时间*/_sec = 6;_usec = 0;/*等待聊天*/retval = select(maxfd+1, &rfds, NULL, NULL, &tv);if(retval == -1){printf("select出错,与该客户端连接的程序将退出\n");break;}else if(retval == 0){printf("waiting...\n");continue;}else{/*⽤户输⼊信息了*/if(FD_ISSET(0, &rfds)){/******发送消息*******/memset(buf,0,sizeof(buf));/*fgets函数:从流中读取BUFLEN-1个字符*/ fgets(buf,BUFLEN,stdin);/*打印发送的消息*///fputs(buf,stdout);if(!strncasecmp(buf,"quit",4)){printf("server 请求终⽌聊天!\n");break;}len = send(newfd,buf,strlen(buf),0);if(len > 0)printf("\t消息发送成功:%s\n",buf);else{printf("消息发送失败!\n");break;}}/*客户端发来了消息*/if(FD_ISSET(newfd, &rfds)){/******接收消息*******/memset(buf,0,sizeof(buf));/*fgets函数:从流中读取BUFLEN-1个字符*/ len = recv(newfd,buf,BUFLEN,0);if(len > 0)printf("客户端发来的信息是:%s\n",buf);else{if(len < 0 )printf("接受消息失败!\n");elseprintf("客户端退出了,聊天终⽌!\n");break;}}}}/*关闭聊天的套接字*/close(newfd);/*是否退出服务器*/printf("服务器是否退出程序:y->是;n->否? ");bzero(buf, BUFLEN);fgets(buf,BUFLEN, stdin);if(!strncasecmp(buf,"y",1)){printf("server 退出!\n");break;}}/*关闭服务器的套接字*/close(sockfd);return0;}客户端client.c#include <stdio.h>#include <stdlib.h>#include <string.h>#include <errno.h>#include <sys/socket.h>#include <arpa/inet.h>#include <netinet/in.h>#include <sys/types.h>#include <unistd.h>#include <sys/time.h>#define BUFLEN 1024#define PORT 6666int main(int argc, char **argv){int sockfd;struct sockaddr_in s_addr;socklen_t len;unsigned int port;char buf[BUFLEN];fd_set rfds;struct timeval tv;int retval, maxfd;/*建⽴socket*/if((sockfd = socket(AF_INET, SOCK_STREAM, 0)) == -1){perror("socket");exit(errno);}elseprintf("socket create success!\n");/*设置服务器ip*/memset(&s_addr,0,sizeof(s_addr));s_addr.sin_family = AF_INET;s_addr.sin_port = htons(PORT);if (inet_aton(argv[1], (struct in_addr *)&s_addr.sin_addr.s_addr) == 0) {perror(argv[1]);exit(errno);}/*开始连接服务器*/if(connect(sockfd,(struct sockaddr*)&s_addr,sizeof(struct sockaddr)) == -1){ perror("connect");exit(errno);}elseprintf("conncet success!\n");while(1){FD_ZERO(&rfds);FD_SET(0, &rfds);maxfd = 0;FD_SET(sockfd, &rfds);if(maxfd < sockfd)maxfd = sockfd;_sec = 6;_usec = 0;retval = select(maxfd+1, &rfds, NULL, NULL, &tv);if(retval == -1){printf("select出错,客户端程序退出\n");break;}else if(retval == 0){printf("waiting...\n");continue;}else{/*服务器发来了消息*/if(FD_ISSET(sockfd,&rfds)){/******接收消息*******/bzero(buf,BUFLEN);len = recv(sockfd,buf,BUFLEN,0);if(len > 0)printf("服务器发来的消息是:%s\n",buf);else{if(len < 0 )printf("接受消息失败!\n");elseprintf("服务器退出了,聊天终⽌!\n");break;}}/*⽤户输⼊信息了,开始处理信息并发送*/if(FD_ISSET(0, &rfds)){/******发送消息*******/bzero(buf,BUFLEN);fgets(buf,BUFLEN,stdin);if(!strncasecmp(buf,"quit",4)){printf("client 请求终⽌聊天!\n");break;}len = send(sockfd,buf,strlen(buf),0);if(len > 0)printf("\t消息发送成功:%s\n",buf);else{printf("消息发送失败!\n");break;}}}}/*关闭连接*/close(sockfd);return0;}在程序的服务端输⼊lwp@lwp-linux:~/Desktop/1234$ ./server在程序的客户端输⼊lwp@lwp-linux:~/Desktop/1234$ ./client 192.168.100.80当然这都是我在我的机⼦上截的图,客户端我们可以放到任何⼀台机⼦上,只要保证都能在同⼀个局域⽹下,连到我的IP地址就⾏。
socket tcp会话原理
Socket TCP会话原理一、概述1.1 Socket概念Socket(套接字)是网络通信的基础,它是网络通信的端点,能够实现不同主机之间的数据传输。
1.2 TCP协议TCP(传输控制协议)是一种面向连接的、可靠的、基于字节流的传输层协议,它提供了可靠的数据传输和对数据包进行排序和错误校正的功能。
二、TCP会话建立2.1 三次握手2.1.1 第一次握手:客户端发送SYN报文,告诉服务端客户端想要连接。
2.1.2 第二次握手:服务端接收到客户端的SYN报文后,发送SYN+ACK报文,告诉客户端已经收到请求,愿意接受连接。
2.1.3 第三次握手:客户端接收到服务端的SYN+ACK报文后,发送ACK报文确认,表示连接建立成功。
2.2 会话数据传输在TCP会话建立成功后,双方可以进行数据的传输,数据包会通过网络传输到目的地,并且在接收端按序组装成完整的数据流。
三、TCP会话终止3.1 四次挥手3.1.1 第一次挥手:客户端发送FIN报文,表示数据发送完毕。
3.1.2 第二次挥手:服务端接收到FIN报文后,发送ACK报文,表示收到了客户端的结束信号。
3.1.3 第三次挥手:服务端发送FIN报文,表示服务端数据发送完毕。
3.1.4 第四次挥手:客户端接收到服务端的FIN报文后,发送ACK报文,表示收到了服务端的结束信号。
四、TCP会话的特点4.1 可靠性TCP提供了可靠的数据传输,通过序列号、确认和重传机制来确保数据的正确性和完整性。
4.2 有序性TCP会话可以保证数据包的有序到达,不会出现数据包乱序的情况。
4.3 全双工TCP会话是全双工的,双方可以同时进行数据的发送和接收,实现真正的双向通信。
五、TCP会话的应用5.1 网络通信TCP会话被广泛应用于各种网络通信场景,如HTTP、FTP等应用层协议都是基于TCP协议的。
5.2 远程登入SSH等远程登入工具使用TCP会话来建立客户端与服务端之间的连接,实现远程管理和操作。
socket编程聊天室基本流程
socket编程聊天室基本流程
1. 客户端连接服务端
客户端程序先会建立和服务端程序的连接,一般来说客户端程序需要指定服务端程序的ip地址和端口号,通过使用socket函数来建立一个TCP连接,如果连接成功的话,就会返回一个相应的套接字描述符。
2. 客户端发送消息
客户端程序在连接成功后,就可以向服务端发送消息,将需要发送的数据通过使用send函数发送到服务端,服务端收到数据后,就可以做出相应的处理。
3. 服务端接收客户端消息
同样也是使用recv函数来接收客户端发来的消息,当服务端收到数据后,就可以进行相应的处理,如果是聊天室中的话,就可以把客户端发送来的消息转发给其他的客户端。
4. 服务端向客户端发送消息
服务端在收到客户端发来的消息后,就可以把处理完的结果发送到客户端,使用send函数就可以把数据发送到客户端,当客户端收到消息后,就可以将消息转发给用户。
5. 客户端关闭连接
客户端程序在使用完聊天室后,就可以选择关闭连接,只需要调用close函数就可以关闭相应的套接字描述符,当服务端收到客户端关闭请求后,就会向客户端发送确认信号,然后就可以关闭客户端的
连接。
C++基于socketUDP网络编程实现简单聊天室功能
C++基于socketUDP⽹络编程实现简单聊天室功能本⽂实例为⼤家分享了C++基于socket UDP实现简单聊天室功能的具体代码,供⼤家参考,具体内容如下0.通信步骤流程图(左:服务器;右:客户端;)1.服务器代码1.1服务器类头⽂件(CServer_UDP.h)#pragma once#include <winsock2.h>class CServer_UDP{public:CServer_UDP();void SendMsg(const char sendBuf[]);void RecMsg();~CServer_UDP();private:SOCKET m_sServer;struct sockaddr_in m_SocAddrClient; //建⽴连接时,⽤于保存客户端信息bool m_terminal;};1.2服务器类源⽂件(CServer_UDP.cpp)#define _WINSOCK_DEPRECATED_NO_WARNINGS#include "CServer_UDP.h"#include <iostream>#pragma comment(lib, "ws2_32.lib")CServer_UDP::CServer_UDP():m_terminal(false){//必须进⾏如下初始化,否则socket()会返回10093错误//初始化WSAWORD sockVersion = MAKEWORD(2, 2);WSADATA wsaData;if (WSAStartup(sockVersion, &wsaData) != 0) //通过⼀个进程初始化ws2_32.dll{std::cout << "Initialize WSA failed" << std::endl;return;}//初始化UDDP套接字m_sServer = socket(AF_INET, SOCK_DGRAM, 0);struct sockaddr_in m_SocAddrserver;m_SocAddrserver.sin_addr.S_un.S_addr = 0;//htonl(INADDR_ANY);m_SocAddrserver.sin_family = AF_INET;m_SocAddrserver.sin_port = htons(8090);int ret = bind(m_sServer, (sockaddr*)&m_SocAddrserver, sizeof(m_SocAddrserver));if (ret == -1){std::cout << "bind failed!" << std::endl;WSACleanup();}else{//此处必须赋初值,不然会导致服务器端⽆法正常发送int len_Client = sizeof(sockaddr);char recBuf[1025];int len = recvfrom(m_sServer, recBuf, 1024, 0, (sockaddr*)&m_SocAddrClient, &len_Client);if (len > 0){recBuf[len] = '\0';std::cout << "Client say:" << recBuf << std::endl;}}}void CServer_UDP::SendMsg(const char sendBuf[]){int ret = sendto(m_sServer, sendBuf, strlen(sendBuf), 0, (sockaddr*)&m_SocAddrClient, sizeof(m_SocAddrClient)); if (ret == -1){std::cout << "send failed" << std::endl;std::cout << GetLastError()<< std::endl;}}void CServer_UDP::RecMsg(){char recBuf[1025];while (!m_terminal){//std::cout << "Begin rec...(server)" << std::endl;int len = recvfrom(m_sServer, recBuf, 1024, 0, 0, 0);if (len > 0){recBuf[len] = '\0';std::cout << "Client say:" << recBuf << std::endl;}}}CServer_UDP::~CServer_UDP(){closesocket(m_sServer);WSACleanup();}1.3服务器主函数#include <iostream>#include <thread>#include <string>#include "CServer_UDP.h"using namespace std;int main(){CServer_UDP server_UDP;thread recProc(&CServer_UDP::RecMsg, &server_UDP);while (1){//cout << "Pleaes input content:" << endl;string content;cin >> content;server_UDP.SendMsg(content.c_str());}recProc.join();cout << "I love china!" << endl;system("pause");return 0;}2.客户端代码2.1客户端类头⽂件(CClient.h)#pragma once#include <winsock2.h>class CClient{public:CClient();void RecMsg();void SendMsg(const char sendBuf[]);~CClient();private:SOCKET m_sockClient;sockaddr_in m_TargetServer;};2.2客户端类源⽂件(CClient.cpp)#define _WINSOCK_DEPRECATED_NO_WARNINGS#include "CClient.h"#include <iostream>#pragma comment(lib, "ws2_32.lib")CClient::CClient(){//必须进⾏如下初始化,否则socket()会返回10093错误//初始化WSAWORD sockVersion = MAKEWORD(2, 2);WSADATA wsaData;if (WSAStartup(sockVersion, &wsaData) != 0) //通过⼀个进程初始化ws2_32.dll{std::cout << "Initialize WSA failed" << std::endl;return;}m_sockClient = socket(AF_INET, SOCK_DGRAM, 0);m_TargetServer.sin_addr.S_un.S_addr = inet_addr("127.0.0.1");m_TargetServer.sin_family = AF_INET;m_TargetServer.sin_port = htons(8090);if (m_sockClient == -1){std::cout << "Create socket failed!" << std::endl;WSACleanup();}else{//发送信息与服务器建⽴连接(必须加)sendto(m_sockClient, "hello server", strlen("hello server"), 0, (sockaddr*)&m_TargetServer, sizeof(m_TargetServer)); }}void CClient::SendMsg(const char sendBuf[]){sendto(m_sockClient, sendBuf, strlen(sendBuf), 0, (sockaddr*)&m_TargetServer, sizeof(m_TargetServer));}void CClient::RecMsg(){char recBuf[1025];while (1){//std::cout << "Begin rec...(client)" << std::endl;int len = recvfrom(m_sockClient, recBuf, 1024, 0, 0, 0);if (len > 0){recBuf[len] = '\0';std::cout << "Server say: " << recBuf << std::endl;}}}CClient::~CClient(){closesocket(m_sockClient);WSACleanup();}2.3客户端主函数#include <iostream>#include <string>#include <thread>#include "CClient.h"using namespace std;int main(){CClient client_UDP;thread RecProc(&CClient::RecMsg, &client_UDP); while (1){//cout << "Please input content:" << endl;string content;cin >> content;client_UDP.SendMsg(content.c_str());}RecProc.join();cout << "I love china!" << endl;system("pause");return 0;}3.效果图(win7+VS2017)3.1服务端3.2客户端以上就是本⽂的全部内容,希望对⼤家的学习有所帮助,也希望⼤家多多⽀持。
一种基于TCP的网络聊天软件实现
一种基于TCP的网络聊天软件实现1.简介网络聊天软件是在线沟通交流的重要工具。
基于TCP的网络聊天软件可以通过建立TCP连接,实现客户端和服务器之间的实时聊天功能。
本文将介绍一种基于TCP的网络聊天软件实现方法。
2.技术实现(1)客户端和服务器的连接建立客户端与服务器之间的连接可以通过socket编程实现。
客户端创建一个套接字,然后使用服务器的IP地址和端口号将套接字连接到服务器上的套接字。
服务器端负责接受来自客户端的连接请求,并创建一个新的线程以处理客户端的请求。
(2)用户注册和登录功能在网络聊天软件中,用户需要注册和登录才能使用聊天功能。
当用户第一次打开软件时,需要注册一个新的用户账号。
注册时,客户端将用户提供的用户名和密码发送给服务器进行验证,服务器将用户的信息存储到数据库中。
当用户后续登录时,客户端将用户名和密码发送给服务器进行验证,服务器返回登录成功或失败的结果。
(3)用户聊天功能用户登录后,可以与其他在线用户进行聊天。
客户端可以发送消息给服务器,服务器将接收到的消息广播给所有在线用户。
客户端也可以接收其他用户发送的消息,并在界面上显示出来。
为了实现实时聊天功能,客户端和服务器之间可以使用多线程来进行消息的收发。
(4)用户好友管理网络聊天软件通常提供好友管理功能,用户可以添加好友、删除好友,并查看自己的好友列表。
在基于TCP的聊天软件中,客户端可以发送请求给服务器添加或删除好友。
服务器接收到请求后,将对应的操作应用到数据库中保存的用户信息上。
(5)聊天记录存储网络聊天软件通常提供聊天记录存储功能,用户可以查看之前的聊天记录。
在基于TCP的聊天软件中,服务器可以将接受到的消息和发送的消息保存到数据库中。
用户可以在软件界面上选择查看聊天记录,并根据用户名、时间等条件进行。
3.客户端界面设计网络聊天软件的客户端通常包含登录界面、注册界面和聊天界面。
登录界面用于输入用户名和密码进行登录,注册界面用于注册新用户账号,聊天界面用于显示聊天内容和进行聊天操作。
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`槽函数绑定。
基于TCP的简单一对一聊天程序设计
一、课程设计题目:通过套接字连接进行一对一聊天通信二、实验要求:实现一个一对一的聊天程序。
基本过程如下:服务器首先启动,创建套接字后等待客户的连接;客户启动以后,创建套接字,然后和服务器建立连接;连接建立后,客户机和服务器可以通过建立的套接字连接进行通信。
服务器和客户端可以是一台电脑的两个进程,也可以分别部署在两台电脑上。
三、原理概述:套接字Socket是一种双向的通信接口,可以通过这个端口与任何一个具有Socket端口的计算机通信,套接字是网络通信的基础。
Socket在Windows以句柄的形式被创建。
使用Socket进行网络通信必须包含下面的几种信息:双方认可的协议,本地主机的IP地址,本地进程的协议端口,对方主机的IP 地址,对方进程的协议端口。
Socket可分为: 1 数据报套接字(Datagram Sockets)——对于在TCP/IP上实现的WinSock,数据报套接字使用用户数据报协议(UDP)。
数据报套接字提供了一种不可靠的、非连接的数据包通信方式。
2 流式套接字(Stream Sockets)——流式套接字使用传输控制协议(TCP)。
流式套接字可以将数据按顺序无重复地发送到目的地,它提供的是一种可靠的、面向连接的数据传输方式。
不管是对单个的数据报,还是对数据包,流式套接字都提供了一种流式数据传输。
VC++对网络编程的支持有socket支持,Winlnet支持,MAPI和ISAPI支持等。
其中Windows Sockets API是TCP/IP网络环境里,也是Internet上进行开发最为通用的API。
IP地址:IP Address就是依照TCP/IP协议分配给本地主机的网络地址,就向两个进程要通讯,任一进程要知道通讯对方的位置,位置如何来确定,就用对方的IP端口号:用来标识本地通讯进程,方便OS提交数据.就是说进程指定了对方进程的网络IP,但这个IP 只是用来标识进程所在的主机,如何来找到运行在这个主机的这个进程呢,就用端口号.连接:指两个进程间的通讯链路.一个完整的网间进程通信需要由两个进程组成,并且只能使用同一种高层协议。
TCP与UDP客户服务端实现大小写及SOCKET编程实现聊天程序
1.TCP实现大小写转换代码如下import java.io.*;import .*;class TCPServer{public static void main(String argv[]) throws Exception {String ClientSentence;String capitalizedSentence;@SuppressWarnings("resource")ServerSocket welcomeSocket = new ServerSocket(8998);while(true){Socket connectionSocket = welcomeSocket.accept();BufferedReader infromClient =new BufferedReader(new InputStreamReader( connectionSocket.getInputStream()));DataOutputStream outToClient =new DataOutputStream(connectionSocket.getOutputStream());ClientSentence = infromClient. readLine();capitalizedSentence =ClientSentence.toUpperCase() + '\n';outToClient.writeBytes(capitalizedSentence);}}}TCP服务器代码:import java.io.*;import .*;class TCPClient{public static void main(String argv[]) throws Exception {String sentence;String modifiedSentence;BufferedReader infromUser =new BufferedReader(new InputStreamReader(System.in));Socket clientSocket = new Socket("127.0.0.1",8998);DataOutputStream outToServer =new DataOutputStream(clientSocket.getOutputStream());BufferedReader infromServer =new BufferedReader(new InputStreamReader( clientSocket.getInputStream()));sentence = infromUser.readLine();outToServer.writeBytes(sentence + '\n');modifiedSentence = infromServer.readLine();System.out.println("FROM SERVER:"+modifiedSentence);clientSocket.close();}}运行结果截图:2.UDP实现大小写转换UDPServer短代码:import .*;import java.io.*;public class Server {public static void main(String args[])throws SocketException,IOException{DatagramSocket socket;DatagramPacket packet;byte[] buf = new byte[256];int port;InetAddress add;socket = new DatagramSocket(8888);packet = new DatagramPacket(buf,buf.length);boolean b=true;while(b){socket.receive(packet);String s = new String(packet.getData()).trim();System.out.println("服务器接受数据为:"+s);//String str = s-('a'-'A');String str = s.toUpperCase();s=String.valueOf(str);buf = s.getBytes();packet=new DatagramPacket(buf,buf.length,packet.getAddress(),packet.getPort());socket.send(packet);}socket.close();}}UDP客户端代码:import .*;import java.io.*;public class Client {public static void main(String args[])throws SocketException,IOException{DatagramSocket socket = new DatagramSocket();byte[] buf = new byte[256];BufferedReader b = new BufferedReader(new InputStreamReader(System.in));System.out.println("请输入字符串:");String str = b.readLine();char[] c=str.toCharArray();//String str = "a";buf=String.valueOf(c).getBytes();DatagramPacket packet = new DatagramPacket(buf,buf.length,InetAddress.getLocalHost(),8888);socket.send(packet);buf = new byte[256];packet=new DatagramPacket(buf,buf.length);socket.receive(packet);String s=new String(packet.getData()).trim();System.out.println("转换大写为:"+s);socket.close();}}运行结果截图:3.S OCKET编程实现聊天程序服务器代码:package socket;import java.awt.*;import java.awt.event.*;import javax.swing.*;import javax.swing.border.*;import java.io.*;import .BindException;import .ServerSocket;import .Socket;import java.util.ArrayList;import java.util.StringTokenizer;public class Server {private JFrame frame;private JTextArea contentArea;private JTextField txt_message;private JTextField txt_max;private JTextField txt_port;private JButton btn_start;private JButton btn_stop;private JButton btn_send;private JPanel northPanel;private JPanel southPanel;private JScrollPane rightPanel;private JScrollPane leftPanel;private JSplitPane centerSplit;private JList userList;private DefaultListModel listModel;private ServerSocket serverSocket;private ServerThread serverThread;private ArrayList<ClientThread> clients;private boolean isStart = false;// 主方法,程序执行入口public static void main(String[] args) {new Server();}// 执行消息发送public void send() {if (!isStart) {JOptionPane.showMessageDialog(frame, "服务器还未启动,不能发送消息!", "错误",JOptionPane.ERROR_MESSAGE);return;}if (clients.size() == 0) {JOptionPane.showMessageDialog(frame, "没有用户在线,不能发送消息!", "错误",JOptionPane.ERROR_MESSAGE);return;}String message = txt_message.getText().trim();if (message == null || message.equals("")) {JOptionPane.showMessageDialog(frame, "消息不能为空!", "错误",JOptionPane.ERROR_MESSAGE);return;}sendServerMessage(message);// 群发服务器消息contentArea.append("服务器说:" + txt_message.getText() + "\n");txt_message.setText(null);}// 构造放法public Server() {frame = new JFrame("服务器");// 更改JFrame的图标:frame.setIconImage(Toolkit.getDefaultToolkit().createImage(Client.class.getResource("qq.png")));contentArea = new JTextArea();contentArea.setEditable(false);contentArea.setForeground(Color.blue);txt_message = new JTextField();txt_max = new JTextField("30");txt_port = new JTextField("6999");btn_start = new JButton("启动");btn_stop = new JButton("停止");btn_send = new JButton("发送");btn_stop.setEnabled(false);listModel = new DefaultListModel();userList = new JList(listModel);southPanel = new JPanel(new BorderLayout());southPanel.setBorder(new TitledBorder("写消息"));southPanel.add(txt_message, "Center");southPanel.add(btn_send, "East");leftPanel = new JScrollPane(userList);leftPanel.setBorder(new TitledBorder("在线用户"));rightPanel = new JScrollPane(contentArea);rightPanel.setBorder(new TitledBorder("消息显示区"));centerSplit = new JSplitPane(JSplitPane.HORIZONTAL_SPLIT, leftPanel,rightPanel);centerSplit.setDividerLocation(100);northPanel = new JPanel();northPanel.setLayout(new GridLayout(1, 6));northPanel.add(new JLabel("人数上限"));northPanel.add(txt_max);northPanel.add(new JLabel("端口"));northPanel.add(txt_port);northPanel.add(btn_start);northPanel.add(btn_stop);northPanel.setBorder(new TitledBorder("配置信息"));frame.setLayout(new BorderLayout());frame.add(northPanel, "North");frame.add(centerSplit, "Center");frame.add(southPanel, "South");frame.setSize(600, 400);int screen_width = Toolkit.getDefaultToolkit().getScreenSize().width;int screen_height = Toolkit.getDefaultToolkit().getScreenSize().height;frame.setLocation((screen_width - frame.getWidth()) / 2,(screen_height - frame.getHeight()) / 2);frame.setVisible(true);// 关闭窗口时事件frame.addWindowListener(new WindowAdapter() {public void windowClosing(WindowEvent e) {if (isStart) {closeServer();// 关闭服务器}System.exit(0);// 退出程序}});// 文本框按回车键时事件txt_message.addActionListener(new ActionListener() {public void actionPerformed(ActionEvent e) {send();}});// 单击发送按钮时事件btn_send.addActionListener(new ActionListener() {public void actionPerformed(ActionEvent arg0) {send();}});// 单击启动服务器按钮时事件btn_start.addActionListener(new ActionListener() {public void actionPerformed(ActionEvent e) {if (isStart) {JOptionPane.showMessageDialog(frame, "服务器已处于启动状态,不要重复启动!","错误", JOptionPane.ERROR_MESSAGE);return;}int max;int port;try {try {max = Integer.parseInt(txt_max.getText());} catch (Exception e1) {throw new Exception("人数上限为正整数!");}if (max <= 0) {throw new Exception("人数上限为正整数!");}try {port = Integer.parseInt(txt_port.getText());} catch (Exception e1) {throw new Exception("端口号为正整数!");}if (port <= 0) {throw new Exception("端口号为正整数!");}serverStart(max, port);contentArea.append("服务器已成功启动!人数上限:" + max + ",端口:" + port+ "\n");JOptionPane.showMessageDialog(frame, "服务器成功启动!");btn_start.setEnabled(false);txt_max.setEnabled(false);txt_port.setEnabled(false);btn_stop.setEnabled(true);} catch (Exception exc) {JOptionPane.showMessageDialog(frame,exc.getMessage(),"错误", JOptionPane.ERROR_MESSAGE);}}});// 单击停止服务器按钮时事件btn_stop.addActionListener(new ActionListener() {public void actionPerformed(ActionEvent e) {if (!isStart) {JOptionPane.showMessageDialog(frame, "服务器还未启动,无需停止!", "错误",JOptionPane.ERROR_MESSAGE);return;}try {closeServer();btn_start.setEnabled(true);txt_max.setEnabled(true);txt_port.setEnabled(true);btn_stop.setEnabled(false);contentArea.append("服务器成功停止!\n");JOptionPane.showMessageDialog(frame, "服务器成功停止!");} catch (Exception exc) {JOptionPane.showMessageDialog(frame, "停止服务器发生异常!", "错误",JOptionPane.ERROR_MESSAGE);}}});}// 启动服务器public void serverStart(int max, int port) throws .BindException { try {clients = new ArrayList<ClientThread>();serverSocket = new ServerSocket(port);serverThread = new ServerThread(serverSocket, max);serverThread.start();isStart = true;} catch (BindException e) {isStart = false;throw new BindException("端口号已被占用,请换一个!");} catch (Exception e1) {e1.printStackTrace();isStart = false;throw new BindException("启动服务器异常!");}}// 关闭服务器@SuppressWarnings("deprecation")public void closeServer() {try {if (serverThread != null)serverThread.stop();// 停止服务器线程for (int i = clients.size() - 1; i >= 0; i--) {// 给所有在线用户发送关闭命令clients.get(i).getWriter().println("CLOSE");clients.get(i).getWriter().flush();// 释放资源clients.get(i).stop();// 停止此条为客户端服务的线程clients.get(i).reader.close();clients.get(i).writer.close();clients.get(i).socket.close();clients.remove(i);}if (serverSocket != null) {serverSocket.close();// 关闭服务器端连接}listModel.removeAllElements();// 清空用户列表isStart = false;} catch (IOException e) {e.printStackTrace();isStart = true;}}// 群发服务器消息public void sendServerMessage(String message) {for (int i = clients.size() - 1; i >= 0; i--) {clients.get(i).getWriter().println("服务器:" + message + "(多人发送)");clients.get(i).getWriter().flush();}}// 服务器线程class ServerThread extends Thread {private ServerSocket serverSocket;private int max;// 人数上限// 服务器线程的构造方法public ServerThread(ServerSocket serverSocket, int max) {this.serverSocket = serverSocket;this.max = max;}public void run() {while (true) {// 不停的等待客户端的链接try {Socket socket = serverSocket.accept();if (clients.size() == max) {// 如果已达人数上限BufferedReader r = new BufferedReader(newInputStreamReader(socket.getInputStream()));PrintWriter w = new PrintWriter(socket.getOutputStream());// 接收客户端的基本用户信息String inf = r.readLine();StringTokenizer st = new StringTokenizer(inf, "@");User user = new User(st.nextToken(), st.nextToken());// 反馈连接成功信息w.println("MAX@服务器:对不起," +user.getName()+ user.getIp() + ",服务器在线人数已达上限,请稍后尝试连接!");w.flush();// 释放资源r.close();w.close();socket.close();continue;}ClientThread client = new ClientThread(socket);client.start();// 开启对此客户端服务的线程clients.add(client);listModel.addElement(client.getUser().getName());// 更新在线列表contentArea.append(client.getUser().getName()+ client.getUser().getIp() + "上线!\n");} catch (IOException e) {e.printStackTrace();}}}}// 为一个客户端服务的线程class ClientThread extends Thread {private Socket socket;private BufferedReader reader;private PrintWriter writer;private User user;public BufferedReader getReader() {return reader;}public PrintWriter getWriter() {return writer;}public User getUser() {return user;}// 客户端线程的构造方法public ClientThread(Socket socket) {try {this.socket = socket;reader = new BufferedReader(new InputStreamReader(socket.getInputStream()));writer = new PrintWriter(socket.getOutputStream());// 接收客户端的基本用户信息String inf = reader.readLine();StringTokenizer st = new StringTokenizer(inf, "@");user = new User(st.nextToken(), st.nextToken());// 反馈连接成功信息writer.println(user.getName() + user.getIp() + "与服务器连接成功!");writer.flush();// 反馈当前在线用户信息if (clients.size() > 0) {String temp = "";for (int i = clients.size() - 1; i >= 0; i--) {temp += (clients.get(i).getUser().getName() + "/" + clients.get(i).getUser().getIp())+ "@";}writer.println("USERLIST@" + clients.size() + "@" + temp);writer.flush();}// 向所有在线用户发送该用户上线命令for (int i = clients.size() - 1; i >= 0; i--) {clients.get(i).getWriter().println("ADD@" + user.getName() + user.getIp());clients.get(i).getWriter().flush();}} catch (IOException e) {e.printStackTrace();}}@SuppressWarnings("deprecation")public void run() {// 不断接收客户端的消息,进行处理。
【IT专家】Socket编程一实现简易的聊天功能以及文件传输
本文由我司收集整编,推荐下载,如有疑问,请与我司联系Socket编程一实现简易的聊天功能以及文件传输2017/02/21 0 干程序是一件枯燥重复的事,每当感到内心浮躁的时候,我就会找小说来看。
我从小就喜爱看武侠小说,一直有着武侠梦。
从金庸,古龙,梁羽生系列到凤歌(昆仑),孙晓(英雄志)以及萧鼎的(诛仙)让我领略着不一样的江湖。
如果你有好看的武侠系列小说,给我留言哦。
题外话就扯这么多了,接着还是上技术。
看看今天实现的功能效果图: 可以这里使用多台手机进行通讯,【凤歌】我采用的服务器发送消息。
是不是只有发送消息,有些显得太单调了。
好,在发送消息的基础上增加文件传输。
后期会增加视频,音频的传输,增加表情包。
那一起来看看图文消息的效果图,带领大家一起来实现通讯的简易聊天功能。
需要解决的难点: 如何判断socket接收的数据是字符串还是流?如果你已是一名老司机,还请留言给出宝贵意见。
带着这个疑问我们接着往下看。
Socket概述Socket我们称之为”套接字”,用于消息通知系统(如:激光推送),时事通讯系统(如:环信)等等。
用于描述IP地址和端口,是一个通信链的句柄。
网络上的两个程序通过一个双向的通讯连接实现数据的交换,这个双向链路的一端称为一个Socket,一个Socket由一个IP地址和一个端口号唯一确定(如:ServerSocket)。
应用程序通常通过”套接字”向网络发出请求或者应答网络请求。
Socket是TCP/IP协议的一个十分流行的编程界面,但是,Socket所支持的协议种类也不光TCP/IP一种,因此两者之间是没有必然联系的。
在Java环境下,Socket编程主要是指基于TCP/IP协议的网络编程。
java包下有两个类:Socket和ServerSocket,基于TCP协议。
本文针对Socket和ServerSocket作主要讲解。
socket连接建立Socket连接至少需要一对套接字,其中一个运行于客户端,称为。
c#UDPTCP协议简单实现(简单聊天工具)
c#UDPTCP协议简单实现(简单聊天⼯具)长时间没有摸这两个协议,写个代码温习下下⾯是界⾯【服务器界⾯】【登陆界⾯】【好友列表界⾯(我登陆了2个)】【聊天界⾯】下⾯⼤致讲解下⽤到的内容1、⽤户登陆于服务器通信⽤到的tcp协议,服务器接收到⽤户登陆信息(包括ip,端⼝,⽤户名等)后,返回已经登陆的⽤户列表信息(包括ip,端⼝,⽤户名等)给这个⽤户,同时服务器使⽤Udp协议向已经登陆的⽤户发送最新⽤户列表(包括ip,端⼝,⽤户名等)⽤于更新⽤户列表2、⽤户登陆成功后展⽰好友列表,并启动udp协议的监听(叫监听似乎不太合适,暂且这么叫吧形象),⽤以接收好友发来的消息和服务器返回的好友信息(1中提到的发送⽤户列表信息)3、关于聊天有被动接收到消息和主动发送消息先说主动发送消息吧:双击列表的某个好友打开聊天窗⼝,然后发送内容,通过udp协议向好友发送信息被动接收消息:当2中提到的udp监听器接收到消息,则打开聊天窗⼝,并显⽰信息4、⽤户退出时想服务器发送数据退出,⽤到的tcp协议,服务器接到到信息,更新在线⽤户列表并向其他⽤户发送⽤户最新列表进⾏更新(⽤到udp协议)⼝才不⾏,写的有点乱下⾯上代码解释下先来服务器代码,服务器我使⽤了控制台程序1using System;2using System.Collections.Generic;3using System.Text;4using .Sockets;5using System.Threading;6using ;7using System.IO;89namespace QQServer10 {11class Program12 {13public static List<string> userlist = new List<string>();14static TcpListener tl;15static NetworkStream ns;16static void Main(string[] args)17 {18//声明监听对象1920//声明⽹络流2122//IPEndPoint ip=new IPEndPoint(23 tl = new TcpListener(12345);24 tl.Start();25 Console.WriteLine("TcpListener Star");26//开启线程27 Thread th = new Thread(new ThreadStart(listen));28 th.IsBackground = true;29 th.Start();30while (true)31 {32string index = Console.ReadLine();33if (index == "exit")34break;3536 }3738 }39private static void listen()40 {41 Console.WriteLine("TcpListenering...");42while (true)43 {44//获得响应的Socket45 Socket sock = tl.AcceptSocket();46//通过该Socket实例化⽹络流47 ns = new NetworkStream(sock);48//ClientTcp是添加的类,下⾯会做说明49 ClientTcp ct = new ClientTcp(ns);50//ct_MyEvent⽅法注册ClientTcp类的MyEvent事件51 ct.MyEvent += new MyDelegate(ct_MyEvent);52//开启线程53 Thread th = new Thread(new ThreadStart(ct.TcpThread));54 th.IsBackground = true;55 th.Start();56 }57 }585960static void ct_MyEvent(string temp)61 {62if (temp.StartsWith("login:"))63 {64 temp = temp.Replace("login:", "");65 Console.WriteLine("UserLogin:" + temp);66string[] index = temp.Split(';');67if (!ContainsList(index[0]))68 {69 userlist.Add(temp);70 }71 SendUsersToUser(index[0]);72 }73else if (temp.StartsWith("out:"))74 {75 temp = temp.Replace("out:", "");76 Console.WriteLine("UserLoginOut:" + temp);77if (ContainsList(temp))78 {79 RemoveList(temp);80 }81 SendUsersToUser(temp);82 }83 }8485static void SendUsersToUser(string outuser)86 {87string message = GetUserStr();88 UdpClient uc;89foreach (string s in userlist)90 {91string[] _userstrindex=s.Split(';');92if (_userstrindex[0] == outuser)93continue;94string _ipsindex = _userstrindex[1];95string[] _ipindex = _ipsindex.Split(':');96byte[] b = System.Text.Encoding.UTF8.GetBytes("users" + message); 97//向本机的8888端⼝发送数据98 uc = new UdpClient();99 uc.Send(b, b.Length, _ipindex[0], int.Parse(_ipindex[1]));100 }101 }102103static string GetUserStr()104 {105 StringBuilder sb = new StringBuilder();106foreach (string s in userlist)107 {108if (sb.Length > 0)109 sb.Append("#");110 sb.Append(s);111 }112return sb.ToString();113 }114115static bool ContainsList(string str)116 {117foreach (string s in userlist)118 {119if (s.Split(';')[0] == str)120 {121return true;122 }123 }124return false;125 }126127static void RemoveList(string str)128 {129for (int i = userlist.Count - 1; i >= 0; i--)130 {131string s = userlist[i];132if (s.Split(';')[0] == str)133 {134 userlist.Remove(s);135 }136 }137 }138 }139140public delegate void MyDelegate(string temp);141class ClientTcp142 {143//设置⽹络流局部对象144private NetworkStream ns;145//声明类型为MyDelegate的事件MyEvent146public event MyDelegate MyEvent;147//构造函数中接收参数以初始化148public ClientTcp(NetworkStream ns)149 {150this.ns = ns;151 }152//服务器端线程所调⽤的⽅法153public void TcpThread()154 {155//获得相关的封装流156 StreamReader sr = new StreamReader(ns);157string temp = sr.ReadLine();158//接收到客户端消息后触发事件将消息回传159if (!temp.StartsWith("getuser"))160 {161 MyEvent(temp);162 }163 StringBuilder sb = new StringBuilder();164foreach (string s in erlist)165 {166if (sb.Length > 0)167 sb.Append("#");168 sb.Append(s);169 }170 StreamWriter sw = new StreamWriter(ns);171//转换为⼤写后发送消息给客户端172 sw.WriteLine(sb.ToString());173 sw.Flush();174 sw.Close();175 sr.Close();176 }177 }178 }View Code需要注意的地⽅:tl = new TcpListener(12345);这个地⽅使⽤了固定端⼝12345,所有客户端跟服务器进⾏通信必须使⽤这个端⼝Thread th = new Thread(new ThreadStart(ct.TcpThread));th.IsBackground = true;th.Start();这个地⽅为什么使⽤⼀个线程呢当接收到⼀个信息后需要进⾏处理,如果同时有好多信息进来的话容易堵塞,所有⽤线程,并且接收到⼀个信息马上将信息放到 ClientTcp ct = new ClientTcp(ns);这⾥,然后慢慢进⾏处理吧服务器接收到的消息有多种,怎么区分呢有登陆的信息,有退出的信息,有获取列表的信息,我们可以在发送的消息内⽤⼀些字段进⾏标记,例如在头部加上“getuser”等等的=======================================================下⾯是客户端的登陆1using System;2using System.Collections.Generic;3using ponentModel;4using System.Data;5using System.Drawing;6using System.Text;7using System.Windows.Forms;8using .Sockets;9using System.IO;10using ;1112namespace QQClient13 {14public partial class Login : Form15 {16private TcpClient tc;17//声明⽹络流18private NetworkStream ns;19public Login()20 {21 InitializeComponent();22 }2324private void button1_Click(object sender, EventArgs e)25 {26string username = textBox1.Text;27string ipstr = textBox2.Text;28string poitstr = textBox3.Text;2930 IPHostEntry ipe = Dns.GetHostEntry(Dns.GetHostName());31 IPAddress ipa = null;32foreach (IPAddress ip in ipe.AddressList)33 {34if (ip.AddressFamily == .Sockets.AddressFamily.InterNetworkV6) 35continue;36 ipa = ip;37break;38 }3940 StringBuilder sb = new StringBuilder();41 sb.Append("login:");42 sb.Append(username + ";");43 sb.Append(ipa.ToString() + ":");44 Random r = new Random();45int port = r.Next(2000, 65535);46 sb.Append(port.ToString());4748try49 {50 tc = new TcpClient(ipstr, int.Parse(poitstr));51 }52catch53 {54 MessageBox.Show("⽆法连接到主机");55 }56//实例化⽹络流对象57 ns = tc.GetStream();58 StreamWriter sw = new StreamWriter(ns);59 StreamReader sr = new StreamReader(ns);60//将TextBox1的值传给服务器端61 sw.WriteLine(sb.ToString());62 sw.Flush();63//接收服务器端回传的字符串64string users = sr.ReadLine();6566 sr.Close();67 sw.Close();6869 Main main=new Main();70 ername=username;71 ers=users;72 main.Port = port;73 main.ThisIP = ipa.ToString();74 main.ServerIP = textBox2.Text;75 main.ServerPort = textBox3.Text;76this.Hide();77 main.ShowDialog();78 }7980private void button2_Click(object sender, EventArgs e)81 {82 Application.Exit();83 }84 }85 }View Code列表界⾯1using System;2using System.Collections.Generic;3using ponentModel;4using System.Data;5using System.Drawing;6using System.Text;7using System.Windows.Forms;8using .Sockets;9using System.IO;10using System.Threading;11using ;1213namespace QQClient14 {15public partial class Main : Form16 {17public string Username { get; set; }18public string Users { get; set; }19public int Port { get; set; }20public string ServerIP;21public string ServerPort;22public string ThisIP { get; set; }23public static List<Talking> TalkList = new List<Talking>();24public List<User> userList = new List<User>();25public Main()26 {27 InitializeComponent();28 }2930private void Main_Load(object sender, EventArgs e)31 {32//Control.CheckForIllegalCrossThreadCalls = false;33this.Text = Username;34 LoadUser();35 StartListen();36 }3738private void LoadUser()39 {40if (string.IsNullOrEmpty(Users))41return;42this.listView1.Items.Clear();43 userList.Clear();44string[] _userindex = Users.Split('#');45foreach (string s in _userindex)46 {47string[] _index = s.Split(';');48string _username = _index[0];49//string[] _ipinex = _index[1].Split(':');50//string ip = _ipinex[0];51//string port = _ipinex[1];52if (_username != Username)53 {54//TreeNode tn = new TreeNode();55//tn.Text = _username;56//tn.Tag = _index[1];57//this.treeView1.Nodes.Add(tn);5859 ListViewItem lvitem = new ListViewItem();6061 lvitem.ImageIndex = 0;62 lvitem.Text = _username;63 lvitem.Tag = _index[1];64this.listView1.Items.Add(lvitem);65 userList.Add(new User() { UserName = _username, Ips = _index[1] });66 }67 }697071private void button2_Click(object sender, EventArgs e)72 {73 Application.Exit();74 }7576private void button1_Click(object sender, EventArgs e)77 {78try79 {80 TcpClient tc = new TcpClient(ServerIP, int.Parse(ServerPort));81//实例化⽹络流对象82 NetworkStream ns = tc.GetStream();83 StreamWriter sw = new StreamWriter(ns);84 StreamReader sr = new StreamReader(ns);85//将TextBox1的值传给服务器端86 sw.WriteLine("getuser");87 sw.Flush();88//接收服务器端回传的字符串89 Users = sr.ReadLine();90 sr.Close();91 sw.Close();92 LoadUser();93 }94catch95 { }96 }9798private void Main_FormClosed(object sender, FormClosedEventArgs e)99 {100try101 {102 TcpClient tc = new TcpClient(ServerIP, int.Parse(ServerPort));103//实例化⽹络流对象104 NetworkStream ns = tc.GetStream();105 StreamWriter sw = new StreamWriter(ns);106//将TextBox1的值传给服务器端107 sw.WriteLine("out:" + Username);108 sw.Flush();109 sw.Close();110 iswork = false;111 }112catch113 { }114 Application.Exit();115 }116117private void listView1_MouseDoubleClick(object sender, MouseEventArgs e) 118 {119if (this.listView1.SelectedItems.Count > 0)120 {121 ListViewItem lvitem = this.listView1.SelectedItems[0];122string toname = lvitem.Text;123string toips = lvitem.Tag.ToString();124 Talking t = isHaveTalk(toname);125if (t != null)126 {127 t.Focus();128 }129else130 {131 Talking talk = new Talking();132 erName = Username;133 talk.ToName = toname;134 talk.ToIP = toips;135 TalkList.Add(talk);136 talk.Show();137 }138 }139 }140141private Talking isHaveTalk(string toname)142 {143foreach (Talking tk in TalkList)144 {145if (tk.ToName == toname)146return tk;147 }148return null;149 }150151public static void RemoveTalking(Talking _talk)153foreach (Talking tk in TalkList)154 {155if (tk.ToName == _talk.ToName)156 {157 TalkList.Remove(_talk);158return;159 }160 }161 }162163bool iswork = false;164 UdpClient uc = null;165private void StartListen()166 {167168 iswork = true;169 Thread th = new Thread(new ThreadStart(listen));170//设置为后台171 th.IsBackground = true;172 th.Start();173 }174private void listen()175 {176 uc = new UdpClient(Port);177 IPEndPoint iep = new IPEndPoint(IPAddress.Any, 0);178while (iswork)179 {180//获得Form1发送过来的数据包181string text = System.Text.Encoding.UTF8.GetString(uc.Receive(ref iep)); 182if (text.StartsWith("message"))183 {184 text = text.Substring(7);185int indexof = text.IndexOf("#");186string fromuser = text.Substring(0, indexof);187string message = text.Substring(indexof + 1);188 Talking _tk = isHaveTalk(fromuser);189if (_tk != null)190 {191this.BeginInvoke(new MethodInvoker(delegate()192 {193 _tk.Focus();194 _tk.AddMessage(message, true);195 }));196 }197else198 {199//Talking talk = new Talking(message);200//erName = Username;201//talk.ToName = fromuser;202//talk.ToIP = GetIP(fromuser);203//TalkList.Add(talk);204//talk.Show();205this.BeginInvoke(new MethodInvoker(delegate()206 {207this.CreatTalking(text);208 }));209//Thread th = new Thread(new ParameterizedThreadStart(CreatTalking)); 210//th.IsBackground = true;211//th.Start(text);212 }213//加⼊ListBox214//this.listBox1.Items.Add(text);215 }216else if (text.StartsWith("users"))217 {218 text = text.Substring(5);219 Users = text;220 LoadUser();221 }222 }223 }224225public void CreatTalking(object _text)226 {227string text = _text.ToString();228int indexof = text.IndexOf("#");229string fromuser = text.Substring(0, indexof);230string message = text.Substring(indexof + 1);231 Talking talk = new Talking(message);232 erName = Username;233 talk.ToName = fromuser;234 talk.ToIP = GetIP(fromuser);235 TalkList.Add(talk);236 talk.Show();237 }238239private string GetIP(string toname)240 {241foreach (User user in userList)242 {243if (erName == toname)244return user.Ips;245 }246return"";247 }248 }249public class User250 {251private string userName;252253public string UserName254 {255get { return userName; }256set { userName = value; }257 }258private string ips;259260public string Ips261 {262get { return ips; }263set { ips = value; }264 }265 }266 }View Code聊天界⾯1using System;2using System.Collections.Generic;3using ponentModel;4using System.Data;5using System.Drawing;6using System.Text;7using System.Windows.Forms;8using .Sockets;9using System.Threading;1011namespace QQClient12 {13public partial class Talking : Form14 {15public string UserName { get; set; }16public string ToName { get; set; }17public string ToIP { get; set; }1819 UdpClient uc;20public Talking()21 {22 InitializeComponent();23 }2425string getmessage = string.Empty;26public Talking(string message)27 {28 getmessage = message;29 InitializeComponent();30 }3132private void Talking_Load(object sender, EventArgs e)33 {34 uc = new UdpClient();35this.Text = "和" + ToName + "聊天中";36if (!string.IsNullOrEmpty(getmessage))37 {38 ShowTalking();39 AddMessage(getmessage, true);40 }41 }4243private void button1_Click(object sender, EventArgs e) 44 {45string temp = this.textBox1.Text; //保存TextBox⽂本 46//将该⽂本转化为字节数组47byte[] b = System.Text.Encoding.UTF8.GetBytes("message" + UserName + "#" + temp);48//向本机的8888端⼝发送数据49string[] _ip = ToIP.Split(':');50 uc.Send(b, b.Length, _ip[0], int.Parse(_ip[1]));51 AddMessage(temp, false);52this.textBox1.Clear();53 }54public void AddMessage(string str, bool isuser)55 {56int startindex = this.richTextBox1.Text.Length;5758string message = string.Empty;5960if (isuser)61 message = "【" + ToName + "】 " + DateTime.Now.ToString("yyyy-MM-dd HH:mm:ss") + "\n" + str + "\n"; 62else63 message = "【" + UserName + "】 " + DateTime.Now.ToString("yyyy-MM-dd HH:mm:ss") + "\n" + str + "\n"; 64this.richTextBox1.AppendText(message);65this.richTextBox1.Select(startindex, message.Length);66if (isuser)67 {68this.richTextBox1.SelectionAlignment = HorizontalAlignment.Left;69 }70else71 {72this.richTextBox1.SelectionAlignment = HorizontalAlignment.Right;73 }74this.richTextBox1.Select(this.richTextBox1.Text.Length, 0);75 }7677 [System.Runtime.InteropServices.DllImport("user32")]78private static extern long FlashWindow(IntPtr hwnd, bool bInvert);7980private static void FlashWindow(object _handle)81 {82 IntPtr handle = (IntPtr)_handle;83int flashindex = 0;84while (true)85 {86if (flashindex > 5)87break;88 FlashWindow(handle, true);89 flashindex++;90 Thread.Sleep(500);91 }92 }9394public void ShowTalking()95 {96 Thread _thread = new Thread(FlashWindow);97 _thread.IsBackground = true;98 _thread.Start(this.Handle);99 }100101private void Talking_FormClosed(object sender, FormClosedEventArgs e)102 {103 Main.RemoveTalking(this);104 }105106private void button2_Click(object sender, EventArgs e)107 {108this.Close();109 }110 }111 }View Code⼤致总结下:tcp必须建⽴连接才可以进⾏通信udp不需要建⽴通信但是两者都需要⼀个监听来接收消息。
c语言实现tcp简单聊天程序的项目概述
项目名称:C语言实现TCP简单聊天程序
项目概述:
本项目旨在使用C语言编写一个简单的TCP聊天程序,实现客户端和服务器之间的实时通信。
通过这个项目,可以学习到TCP协议的基本概念、套接字编程以及多线程等知识。
功能需求:
1. 客户端和服务器之间能够建立连接。
2. 客户端和服务器之间能够发送和接收消息。
3. 客户端和服务器之间能够实现实时通信。
4. 客户端和服务器之间能够处理多个并发连接。
技术选型:
1. 编程语言:C语言
2. 网络库:BSD套接字库(socket)
3. 线程库:POSIX线程库(pthread)
项目结构:
1. 服务器端代码:包括服务器端主函数、创建套接字、绑定地址、监听连接、接受客户端连接、处理客户端请求、发送消息等功能。
2. 客户端代码:包括客户端主函数、创建套接字、连接服务器、发送消息、接收消息等功能。
3. 辅助函数:包括字符串处理、错误处理等辅助功能的函数。
开发计划:
1. 设计并实现服务器端代码。
2. 设计并实现客户端代码。
3. 测试并调试程序,确保功能正确无误。
4. 编写文档,记录项目的开发过程和使用方法。
基于SOCKET实现即时通讯聊天
/******************************************************************* Description:* TCP协议传输测试,客户端** Usage:* sender [-p:int] [-r:IP] [-n:x] [-b:x] [-t:x]* -p:int 服务器监听端口* -r:IP 服务器IP* -n:x 发送包的次数* -b:x 发送包的大小* -t:x 发送间隔* c1-2015/12/26*****************************************************************/#include <stdio.h>#include <stdlib.h>#include <winsock2.h>#pragma comment(lib, "wsock32.lib")#define DEFAULT_PORT 8888 //默认端口号#define DEFAULT_COUNT 25 //默认发送次数#define DEFAULT_CHAR 'a' //默认填充字符#define DEFAULT_BUFFER_LENGTH 8192 //默认包大小是8K#define DEFAULT_INTERV AL 1000 //默认间隔时间是1秒#define DEFAULT_PER_COUNT 1 //默认每一次发送的包个个数BOOL bConnect = FALSE; // 先连接服务器标志int iPort = DEFAULT_PORT;int itime = DEFAULT_INTERV AL;char cChar = DEFAULT_CHAR;int dwCount = DEFAULT_COUNT;int dwLength = DEFAULT_BUFFER_LENGTH;int dwPcount = DEFAULT_PER_COUNT;char szRecipient[128]; // 服务器地址/********************************************** Function: usage* Description:* 打印帮助信息并退出********************************************/void tip(char *name){printf("usage: %s [-p:int] [-r:IP] [-n:x] [-b:x] [-d:c] [-m:x]\n\n", name);printf(" -p:int 服务器监听端口, 缺省为%d\n", DEFAULT_PORT);printf(" -r:IP 服务器IP\n");printf(" -n:x 发送数据次数, 缺省为%d次\n", DEFAULT_COUNT);printf(" -b:x 发送包的大小,缺省为%d字节\n",DEFAULT_BUFFER_LENGTH);printf(" -t:x 发送间隔时间,缺省为%d秒\n",DEFAULT_INTERV AL);printf(" -m:x 每次发送包的个数,缺省值为%d个\n",DEFAULT_PER_COUNT);ExitProcess(1);}/********************************************** Function: ValidateArgs* Description:* 命令行解析********************************************/void ValidateArgs(int argc, char **argv){int i;if (argc < 2)tip(argv[0]);for (i = 1; i < argc; i++){if (strlen(argv[i]) <= 3 || strchr("-/", *argv[i]) == NULL){continue;}switch (tolower(argv[i][1])){case 'p':if (strlen(argv[i]) > 3)iPort = atoi(&argv[i][3]);break;case 'r':if (strlen(argv[i]) > 3)strcpy(szRecipient, &argv[i][3]);break;case 'n':if (strlen(argv[i]) > 3)dwCount = atol(&argv[i][3]);break;case 'b':if (strlen(argv[i]) > 3)dwLength = atol(&argv[i][3]);break;case 't':if (strlen(argv[i]) > 3)itime = atol(&argv[i][3]);break;case 'm':if(strlen(argv[i])>3)dwPcount=atol(&argv[i][3]);break;default:tip(argv[0]);break;}}}int main(int argc, char **argv){WSADATA wsd;SOCKET s;char *sendbuf=NULL;int ret;int i,j;SOCKADDR_IN serverIP;ValidateArgs(argc, argv);if (WSAStartup(MAKEWORD(2, 2), &wsd) !=NO_ERROR) {printf("WSAStartup() failed!\n");return 1;}//TCP客户端启动s = socket(AF_INET, SOCK_STREAM, 0);if (s == INV ALID_SOCKET) {printf("socket() failed: %d\n", WSAGetLastError());return 1;}// 服务器地址设置serverIP.sin_family = AF_INET;serverIP.sin_port = htons((short)iPort);serverIP.sin_addr.s_addr = inet_addr(szRecipient);if (serverIP.sin_addr.s_addr== INADDR_NONE){struct hostent *host = NULL;host = gethostbyname(szRecipient);if (host)CopyMemory(&serverIP.sin_addr, host->h_addr_list[0],host->h_length);else{printf("gethostbyname() failed: %d\n", WSAGetLastError());WSACleanup();return 1;}}printf("服务器监听端口:%d\t发送包的次数: %d\n",iPort, dwCount); printf("发送包的大小:%d\t包的时间间隔:%d\n",dwLength, itime); printf("每次发送包的个数:%d\n",dwPcount);//设置发送缓冲区sendbuf =(char *) GlobalAlloc(GMEM_FIXED, dwLength);if (!sendbuf){printf("GlobalAlloc() failed: %d\n", GetLastError());return 1;}sendbuf[dwLength-1] = '\0';memset(sendbuf, cChar, (dwLength-1));//连接服务器//依照指定次数和发送间隔发送数据包for (i = 0; i<dwCount-(i*dwPcount); i++){for(j=0;j<dwPcount;j++){s = socket(AF_INET, SOCK_STREAM, 0);if (connect(s, (SOCKADDR *)&serverIP, sizeof(serverIP)) ==SOCKET_ERROR){printf("connect() failed: %d\n", WSAGetLastError());closesocket(s);WSACleanup();return 1;}ret = send(s, sendbuf, dwLength, 0);if (ret == SOCKET_ERROR){printf("send() failed: %d\n", WSAGetLastError());break;}else if ( ret == 0)break;closesocket(s);}Sleep(itime);}closesocket(s);GlobalFree(sendbuf);WSACleanup();return 0;}/**************************c1-2015.12.26**************************/#include <stdio.h>#include <stdlib.h>#include <winsock2.h>#pragma comment(lib, "wsock32.lib")#define DEFAULT_PORT 8888#define DEFAULT_LISTEN_QUEUE 1000#define MAX_BUF_LENGTH 10240int main(void){WSADATA wsd;SOCKET servListen, servAccept;char *recvBuf = NULL;int ret;int dwTcpClientSize;SOCKADDR_IN tcpClienter, local;//初始化socket环境if (WSAStartup(MAKEWORD(2, 2), &wsd) != 0){printf("WSAStartup() failed!\n");return 1;}//TCP服务器启动设置servListen = socket(AF_INET, SOCK_STREAM, 0);if (servListen == INV ALID_SOCKET){printf("socket() failed: %d\n", WSAGetLastError());return 1;}memset(&local, 0, sizeof(local));local.sin_family = AF_INET;local.sin_addr.s_addr = htonl(INADDR_ANY);local.sin_port = htons(DEFAULT_PORT);//绑定本地地址if (bind(servListen, (SOCKADDR *)&local, sizeof(local)) == SOCKET_ERROR) {printf("bind() failed: %d\n", WSAGetLastError());return 1;}//设置监听队列长度if (listen(servListen, DEFAULT_LISTEN_QUEUE) == -1){printf("listen() failed: %d\n", WSAGetLastError());return 1;}//设置接收缓冲区recvBuf =(char *) GlobalAlloc(GMEM_FIXED, MAX_BUF_LENGTH);if (!recvBuf){printf("GlobalAlloc() failed: %d\n", GetLastError());return 1;}memset(recvBuf,0, sizeof(MAX_BUF_LENGTH));printf("等待连接......\n");dwTcpClientSize = sizeof(tcpClienter);while(1){servAccept = accept(servListen, (struct sockaddr *)&tcpClienter, &dwTcpClientSize);if ( servAccept == INV ALID_SOCKET){printf("accept() failed: %d\n", WSAGetLastError());break;}ret = recv(servAccept, recvBuf, sizeof(recvBuf), 0);if (ret < 0){printf("recv() failed: %d\n", WSAGetLastError());break;}ret=ret*2*1024;printf("\n------------------------------------------------\n");printf("from %s recived %d bytes\n",inet_ntoa(tcpClienter.sin_addr),ret);printf("------------------------------------------------\n");closesocket(servAccept);GlobalFree(recvBuf);}closesocket(servListen);GlobalFree(recvBuf);WSACleanup();return 0;}。
socket编程TCP实现简单聊天功能
public void windowClosing(WindowEvent e) {
int a = JOptionPane.showConfirmDialog(null, "确定 关闭吗?", "温馨提示",
ss.close(); if (reader != null)
reader.close(); if (writer != null)
writer.close(); } catch (IOException e) {
// TODO Auto-generated catch block e.printStackTrace(); } } } import java.io.BufferedReader; import java.io.IOException; import java.io.InputStreamReader; import java.io.PrintWriter; import .Socket; /*这个类是服务器端的等待客户端发送信息*/ public class ListenerClient extends Thread { BufferedReader reader; PrintWriter writer; ServerUI ui; Socket client; public ListenerClient(ServerUI ui, Socket client) { this.ui = ui; this.client=client; this.start(); } //为每一个客户端创建线程等待接收信息,然后把信息广播出去
true); writer.println(msg);
Socket编程一实现简易的聊天功能以及文件传输
Socket编程一实现简易的聊天功能以及文件传输功能效果图:可以这里使用多台手机进行通讯,【凤歌】我采用的服务器发送消息。
是不是只有发送消息,有些显得太单调了。
好,在发送消息的基础上增加文件传输。
后期会增加视频,音频的传输,增加表情包。
那一起来看看图文消息的效果图,带领大家一起来实现通讯的简易聊天功能。
需要解决的难点:如何判断socket接收的数据是字符串还是流?如果你已是一名老司机,还请留言给出宝贵意见。
带着这个疑问我们接着往下看。
Socket概述Socket我们称之为”套接字”,用于消息通知系统(如:激光推送),时事通讯系统(如:环信)等等。
用于描述IP地址和端口,是一个通信链的句柄。
网络上的两个程序通过一个双向的通讯连接实现数据的交换,这个双向链路的一端称为一个Socket,一个Socket由一个IP地址和一个端口号唯一确定(如:ServerSocket)。
应用程序通常通过”套接字”向网络发出请求或者应答网络请求。
Socket是TCP/IP协议的一个十分流行的编程界面,但是,Socket 所支持的协议种类也不光TCP/IP一种,因此两者之间是没有必然联系的。
在Java环境下,Socket编程主要是指基于TCP/IP协议的网络编程。
包下有两个类:Socket和ServerSocket,基于TCP协议。
本文针对Socket和ServerSocket作主要讲解。
socket连接建立Socket连接至少需要一对套接字,其中一个运行于客户端,称为ClientSocket ,另一个运行于服务器端,称为ServerSocket。
套接字之间的连接过程分为三个步骤:服务器监听,客户端请求,连接确认。
步骤如下:服务器监听:服务器端套接字并不定位具体的客户端套接字,而是处于等待连接的状态,实时监控网络状态,等待客户端的连接请求客户端请求:指客户端的套接字提出连接请求,要连接的目标是服务器端的套接字。
为此,客户端的套接字必须首先描述它要连接的服务器的套接字,指出服务器端套接字的地址和端口号,然后就向服务器端套接字提出连接请求。
python基于tcp协议的聊天程序设计流程
python基于tcp协议的聊天程序设计流程Python基于TCP协议的聊天程序设计流程本文将分步骤介绍如何使用Python编写基于TCP协议的聊天程序。
这个程序将允许两个或多个用户彼此聊天,连接到服务器以进行实时交流。
实现这个聊天程序的主要目标是使用Python的socket模块来建立TCP连接,并设计一个简单的聊天界面,使用户能够发送和接收消息。
步骤1:导入所需的模块首先,我们需要导入Python标准库中的socket和threading模块。
socket 模块将用于建立TCP连接,而threading模块将用于处理并发连接请求。
步骤2:创建用于监听连接请求的服务器接下来,我们需要创建一个服务器对象,用于监听用户的连接请求。
服务器对象将使用socket模块的socket()函数,并指定通信协议为AF_INET (使用IPv4地址)和SOCK_STREAM(使用TCP协议)。
我们还需要将服务器绑定到一个特定的IP地址和端口号,并使用socket对象的bind()函数实现。
最后,我们使用socket对象的listen()函数来使服务器进入监听模式,等待连接请求。
步骤3:接受客户端的连接请求一旦服务器进入监听模式,它就可以开始接受客户端的连接请求。
我们可以使用socket对象的accept()函数来阻塞并等待客户端的连接请求。
接受连接请求后,我们将会得到一个新的套接字对象和客户端的地址。
我们可以使用这个套接字对象来与客户端进行通信。
步骤4:为每个客户端创建一个线程为了支持多个并发连接,我们需要为每个客户端创建一个线程。
我们可以使用threading模块的Thread类来创建线程。
在每个线程中,我们将会使用套接字对象来处理与该客户端的通信。
接收到客户端的消息后,我们可以对消息进行处理,并将其广播给其他用户。
步骤5:设计聊天界面为了使用户能够发送和接收消息,我们需要设计一个简单的聊天界面。
在这个界面中,用户可以输入消息并将其发送到服务器。
怎么使用Socket实现局域网聊天
怎么使用Socket实现局域网聊天局域网通常是分布在一个有限地理范围内的网络系统,一般所涉及的地理范围只有几公里。
局域网专用性非常强,具有比较稳定和规范的拓扑结构。
这篇文章主要为大家详细介绍了C#使用Socket实现局域网聊天的方法,具有一定的参考价值,感兴趣的小伙伴们可以参考一下C#代码:servlet服务端using System;using System.Collections.Generic;using System.Drawing;using System.Windows.Forms;using ;using .Sockets;using System.Threading;using System.IO;using System.Text;using System.Text.RegularExpressions;namespace Server{public partial class MainForm : Form{private TcpListener listener;private Dictionary socketList;private bool tag = true;private StringBuilder charList;public MainForm(){InitializeComponent();Control.CheckForIllegalCrossThreadCalls = false;}void Bu_StartClick(object sender, EventArgs e){cb_chatList.Items.Clear();selectChat.Text="";int port = 8888;//创建服务端,并且启动try{listener = new TcpListener(IPAddress.Parse(ipAddress()),port);listener.Start();bu_Start.Enabled = false;bu_stop.Enabled = true;}catch(Exception ex){MessageBox.Show("服务器启动失败,原因:"+ex.Message);bu_Start.Enabled = true;bu_stop.Enabled = false;return;}selectChat.Text = "服务器启动成功,访问IP:"+ipAddress()+" 端口号:"+port;//记录住连接的客户端socketList = new Dictionary();charList = new StringBuilder();//使用多线程,用于多个客户端接入Thread th = new Thread(new ThreadStart(executeTask));th.Start();}public void executeTask(){while(tag){//等待用户连接TcpClient client = null;try{client = listener.AcceptT cpClient();}catch(Exception){}Thread th = new Thread(executeRead); th.Start((Object)client);}}public void executeRead(Object pamars) {//永久监听读取客户端TcpClient client = pamars as TcpClient; while(tag){NetworkStream ns = client.GetStream(); StreamReader sr = new StreamReader(ns); String msg = String.Empty;String people = String.Empty;try {msg = sr.ReadLine();if(msg.IndexOf("")!=-1){msg = Regex.Split(msg,"=")[1];cb_chatList.Items.Add(msg);charList.Append(msg).Append("<@>");socketList.Add(msg,client);msg = "欢迎【"+msg+"】光临";}selectChat.AppendText(msg.Replace("","\r\n"));sendMsg(String.Empty,msg);} catch (Exception) {//MessageBox.Show(ex.Message.ToString());break;}}}public void sendMsg(String target,String msg){if(String.Empty!=target){TcpClient client = socketList[target];StreamWriter sw = new StreamWriter(client.GetStream());sw.WriteLine(msg);sw.Flush();}else{Dictionary.KeyCollection keyColl = socketList.Keys;foreach (String name in keyColl){StreamWriter sw = new StreamWriter(socketList[name].GetStream());sw.WriteLine(msg+"<@=@>"+charList.ToString());sw.Flush();}}}/*根据计算名获取IP地址*/public String ipAddress(){IPAddress[] address = Dns.GetHostAddresses(Dns.GetHostName());return address[2].T oString();}void ServerFromFormClosing(object sender, FormClosingEventArgs e){e.Cancel = false;if(tag)tag = false;if(listener!=null)listener.Stop();}void Bu_stopClick(object sender, EventArgs e){bu_Start.Enabled = true;bu_stop.Enabled = false;if(tag)tag = false;if(listener!=null)listener.Stop();}}Client客户端using System;using System.Drawing;using System.Windows.Forms;using System.Threading;using ;using .Sockets;using System.IO;using System.Text;using System.Text.RegularExpressions;namespace Client{public partial class MainForm : Form{private System.Windows.Forms.Timer closeWindowTimer; private StreamReader sr;private StreamWriter sw;private TcpClient tc;private ClientLong cl;private bool tag = true;public MainForm(T cpClient tcp,ClientLong clo){cl = clo;tc = tcp;InitializeComponent();Control.CheckForIllegalCrossThreadCalls = false;bu_simple.Hide();}void ClientFromLoad(object sender, EventArgs e)PiayCheckedChanged();}/*事件方法*/public void PiayCheckedChanged(){closeWindowTimer = new System.Windows.Forms.Timer(); closeWindowTimer.Interval = 1000; closeWindowTimer.Tick += new EventHandler(theout); closeWindowTimer.Start();}/*执行的事件*/public void theout(object source, EventArgs e){//这里单独开一个线程用来显示信息try{Thread t1 = new Thread(new ThreadStart(readMsg));t1.Start();}catch(Exception){}}void readMsg(){if(tag && tc!=null){sr = new StreamReader(tc.GetStream());String msg = sr.ReadLine();String[] address = Regex.Split(msg,"<@=@>"); chatText.AppendT ext(address[0].Replace("","\r\n"));address = Regex.Split(address[1],"<@>");cb_chatList.Items.Clear();foreach (String s in address){if(!String.IsNullOrEmpty(s) && s != cl.clientName)cb_chatList.Items.Add(s);}}}void Button1Click(object sender, EventArgs e){if(String.IsNullOrEmpty(textBox2.Text)){MessageBox.Show("请输入消息");return;}sw = new StreamWriter(tc.GetStream());sw.WriteLine(""+cl.clientName+""+DateTime.Now.ToString("yyyy-MM-dd HH:mm:ss")+""+textBox2.Text);textBox2.Text = "";sw.Flush();}void Bu_exitClick(object sender, EventArgs e){MainFormFormClosing(null,null);}void Button2Click(object sender, EventArgs e){chatText.T ext = "";}void MainFormFormClosing(object sender, FormClosingEventArgs e){closeWindowTimer.Stop();cl.Close();tag = false;if(sr!=null)sr.Close();if(sw!=null)sw.Close();}void Bu_simpleClick(object sender, EventArgs e){String selected = cb_chatList.Text;if(selected==null){MessageBox.Show("请选择单聊对象");return;}}}}补充:局域网、校园网安全维护方法校园网络分为内网和外网,就是说他们可以上学校的内网也可以同时上互联网,大学的学生平时要玩游戏购物,学校本身有自己的服务器需要维护;在大环境下,首先在校园网之间及其互联网接入处,需要设置防火墙设备,防止外部攻击,并且要经常更新抵御外来攻击;由于要保护校园网所有用户的安全,我们要安全加固,除了防火墙还要增加如ips,ids等防病毒入侵检测设备对外部数据进行分析检测,确保校园网的安全;外面做好防护措施,内部同样要做好防护措施,因为有的学生电脑可能带回家或者在外面感染,所以内部核心交换机上要设置vlan隔离,旁挂安全设备对端口进行检测防护;内网可能有ddos攻击或者arp病毒等传播,所以我们要对服务器或者电脑安装杀毒软件,特别是学校服务器系统等,安全正版安全软件,保护重要电脑的安全;对服务器本身我们要安全server版系统,经常修复漏洞及更新安全软件,普通电脑一般都是拨号上网,如果有异常上层设备监测一般不影响其他电脑。
客户端开发教程:学会使用常见的聊天功能(八)
对于现代人来说,聊天已经成为日常生活中不可或缺的一部分。
随着智能手机的普及和即时通讯软件的发展,我们可以方便地与亲朋好友、同事甚至陌生人进行交流。
而作为开发者,如果学会使用常见的聊天功能,不仅可以满足用户需求,还可以提升自己的技术水平。
一、聊天功能的基本实现在客户端开发中,实现聊天功能的第一步是建立通信连接。
最常见的方式是使用Socket,通过TCP或UDP协议与服务器进行通信。
建立连接后,客户端可以发送消息给服务器,服务器将消息转发给其他用户,实现实时的交流。
此外,还需要考虑一些常见的功能,如消息的加密解密、用户的身份认证等。
二、聊天记录的存储与展示在聊天应用中,消息的存储和展示是非常重要的功能。
一般来说,我们可以使用数据库来保存聊天记录,比如可以使用SQLite作为本地数据库,或者使用云存储服务如Firebase来实现远程数据的存储。
在展示方面,可以使用RecyclerView等组件来展示消息列表,并且可以支持多种消息类型的展示,如文本消息、图片消息、语音消息等。
三、聊天界面的设计与交互聊天界面是用户与聊天功能进行交互的主要界面,所以设计一个好用、美观的界面是至关重要的。
首先,需要考虑到基本的元素,如聊天消息的气泡、头像、时间等。
其次,还可以添加一些增强用户体验的功能,如消息的撤回、消息的多选删除、表情包的支持等。
同时,还要注意聊天界面的流畅性和响应速度,避免卡顿和延迟。
四、聊天通知与提醒为了提高用户的使用体验,聊天应用需要及时提醒用户有新消息到来。
在Android平台上,可以使用通知栏进行消息的推送。
当接收到新消息时,可以通过通知栏显示消息的内容,并且可以通过点击通知栏的方式打开聊天界面。
同时,也要考虑到用户的个人偏好,可以提供一些设置选项,让用户自定义通知的显示方式。
五、聊天功能的优化与扩展随着用户量的增加和功能的不断扩展,聊天应用也面临一些挑战和需求。
为了提供更好的用户体验,需要进行性能方面的优化,如减少网络请求的次数、缓存用户数据等。
java网络编程一:Socket用法,简单模拟一对一聊天
java⽹络编程⼀:Socket⽤法,简单模拟⼀对⼀聊天1、socket和serverSocket通信简单介绍如下,注意客户端与服务器端是怎么交换数据的2、模拟qq聊天功能,实现客户端与服务器(⼀对⼀)的聊天功能服务器端代码:[java]01. <span style="font-size:16px;">package ;02.03. import java.io.DataInputStream;04. import java.io.DataOutputStream;05. import java.io.IOException;06. import .ServerSocket;07. import .Socket;08. import java.util.Scanner;09.10. /**11. * 模拟qq聊天功能:实现客户端与服务器(⼀对⼀)的聊天功能,客户端⾸先发起聊天,输⼊的内容在服务器端和客户端显⽰,12. * 然后服务器端也可以输⼊信息,同样信息也在客户端和服务器端显⽰13. */14.15. // 服务器类16. public class ChatServer {17. private int port = 8189;// 默认服务器端⼝18.19. public ChatServer() {20. }21.22. // 创建指定端⼝的服务器23. public ChatServer(int port) {24. this.port = port;25. }26.27. // 提供服务28. public void service() {29. try {// 建⽴服务器连接30. ServerSocket server = new ServerSocket(port);31. // 等待客户连接32. Socket socket = server.accept();33. try {34. // 读取客户端传过来信息的DataInputStream35. DataInputStream in = new DataInputStream(socket36. .getInputStream());37. // 向客户端发送信息的DataOutputStream38. DataOutputStream out = new DataOutputStream(socket39. .getOutputStream());40. // 获取控制台输⼊的Scanner41. Scanner scanner = new Scanner(System.in);42. while (true) {43. // 读取来⾃客户端的信息44. String accpet = in.readUTF();45. System.out.println(accpet);46. String send = scanner.nextLine();47. System.out.println("服务器:" + send);48. // 把服务器端的输⼊发给客户端49. out.writeUTF("服务器:" + send);50. }51. } finally {// 建⽴连接失败的话不会执⾏socket.close();52. socket.close();53. }54. } catch (IOException e) {55. e.printStackTrace();56. }57. }58.59. public static void main(String[] args) {60. new ChatServer().service();61. }62. }63. </span>客户端代码:[java]01. <span style="font-size:16px;">package ;02.03. import java.io.DataInputStream;04. import java.io.DataOutputStream;05. import java.io.IOException;06. import .Socket;07. import java.util.Scanner;08.09. /**10. * 注意⽤到的输⼊输出流DataInputStream和DataOutputStream,成对出现,最好⽤字节流11. */12. // 客户端类13. public class ChatClient {14. private String host = "localhost";// 默认连接到本机15. private int port = 8189;// 默认连接到端⼝818916.17. public ChatClient() {18.19. }20.21. // 连接到指定的主机和端⼝22. public ChatClient(String host, int port) {23. this.host = host;24. this.port = port;25. }26.27. public void chat() {28. try {29. // 连接到服务器30. Socket socket = new Socket(host, port);31.32. try {33. // 读取服务器端传过来信息的DataInputStream34. DataInputStream in = new DataInputStream(socket35. .getInputStream());36. // 向服务器端发送信息的DataOutputStream37. DataOutputStream out = new DataOutputStream(socket38. .getOutputStream());39.40. // 装饰标准输⼊流,⽤于从控制台输⼊41. Scanner scanner = new Scanner(System.in);42.43. while (true) {44. String send = scanner.nextLine();45. System.out.println("客户端:" + send);46. // 把从控制台得到的信息传送给服务器47. out.writeUTF("客户端:" + send);48. // 读取来⾃服务器的信息49. String accpet = in.readUTF();50. System.out.println(accpet);51. }52.53. } finally {54. socket.close();55. }56. } catch (IOException e) {57. e.printStackTrace();58. }59. }60.61. public static void main(String[] args) {62. new ChatClient().chat();63. }64. }65. </span>运⾏结果:注意运⾏的时候要先开服务器,再开客户端,聊天由客户端发起。
Java TCP实现简单的聊天
Java TCP实现简单的聊天服务器代码public class Servlet {public static void main(String[] args) {try {ServerSocket serverSocket=null;serverSocket=new ServerSocket(4567);System.out.println("服务器打开在端口4567等待");while(true){Socket socket=serverSocket.accept(); //监听端口并获取套接字Socketnew Thread(new ThreadTest(socket)).start();}} catch (Exception e) {e.printStackTrace();}}}class ThreadTest implements Runnable{private Socket socket;public ThreadTest(Socket socket){this.socket=socket;}public void run() {try {BufferedReader br=new BufferedReader(new InputStreamReader(socket.getInputStream())); //输出客户端发过来的数据BufferedReader bw=new BufferedReader(new InputStreamReader(System.in)); //往控制台输入信息PrintWriter pw=newPrintWriter(socket.getOutputStream()); //向客户端写入数据while(true){System.out.println("客户端(IP地址是)"+socket.getInetAddress().getHostAddress()+":"+socket.getPor t()+"发来"+br.readLine());String lineString=bw.readLine();if(!lineString.equals("bye")){System.out.println("服务端输入"+lineString);pw.println(lineString);pw.flush();}else {pw.println(lineString);pw.flush();bw.close();pw.close();br.close();System.out.println("服务器断开...");}}} catch (Exception e) {e.printStackTrace();}}}客户端代码public class Clinet {public static void main(String[] args) throws IOException {Socket socket =null;try {socket=new Socket("localhost",4567);System.out.println("客户端打开");} catch (UnknownHostException e) {e.printStackTrace();} catch (IOException e) {e.printStackTrace();}BufferedReader bu=new BufferedReader(new InputStreamReader(System.in)); //客户端输入数据PrintWriter pw=new PrintWriter(socket.getOutputStream()); //向服务端写入数据BufferedReader bi=new BufferedReader(new InputStreamReader(socket.getInputStream())); //获取服务端的数据//System.out.println("客户端输入"+bu.readLine());while(true){String lineString=bu.readLine(); //获取服务端的数据if(!lineString.equals("bye")){//System.out.println("客户端输入"+lineString);//向服务端输入数据pw.println(lineString);pw.flush();//在获取控制台的数据System.out.println("服务端回复我........"+bi.readLine());}else {pw.println(lineString);pw.flush();bu.close();pw.close();bi.close();System.out.println("客户端断开");}}}本例子主要使用的是流和Socket的基本使用方法实现简单的聊天。
- 1、下载文档前请自行甄别文档内容的完整性,平台不提供额外的编辑、内容补充、找答案等附加服务。
- 2、"仅部分预览"的文档,不可在线预览部分如存在完整性等问题,可反馈申请退款(可完整预览的文档不适用该条件!)。
- 3、如文档侵犯您的权益,请联系客服反馈,我们会尽快为您处理(人工客服工作时间:9:00-18:30)。
计算机网络报告socket编程TCP实现简单聊天功能java网络编程,通过TCP,Socket实现多对一的局域网聊天室可以实现多个客户端连接服务器,服务器接收到信息就会把信息广播到所有的客户端服务端源码:import java.awt.BorderLayout;import java.awt.FlowLayout;import java.awt.event.ActionEvent;import java.awt.event.ActionListener;import java.awt.event.WindowAdapter;import java.awt.event.WindowEvent;import .Socket;import java.util.List;import javax.swing.JButton;import javax.swing.JFrame;import javax.swing.JOptionPane;import javax.swing.JPanel;import javax.swing.JScrollPane;import javax.swing.JTextArea;import javax.swing.JTextField;/*这个类是服务器端的UI*/public class ServerUI extends JFrame {public static void main(String[] args) {ServerUI serverUI = new ServerUI();}public JButton btStart;//启动服务器public JButton btSend;//发送信息按钮public JTextField tfSend;//需要发送的文本信息public JTextArea taShow;//信息展示public Server server;//用来监听客户端连接static List<Socket> clients;//保存连接到服务器的客户端public ServerUI() {super("服务器端");btStart = new JButton("启动服务");btSend = new JButton("发送信息");tfSend = new JTextField(10);taShow = new JTextArea();btStart.addActionListener(new ActionListener() { public void actionPerformed(ActionEvent e) {server = new Server(ServerUI.this);}});btSend.addActionListener(new ActionListener() { public void actionPerformed(ActionEvent e) {server.sendMsg(tfSend.getText());tfSend.setText("");}});this.addWindowListener(new WindowAdapter() { public void windowClosing(WindowEvent e) {int a = JOptionPane.showConfirmDialog(null, "确定关闭吗?", "温馨提示",JOptionPane.YES_NO_OPTION);if (a == 1) {server.closeServer();System.exit(0); // 关闭}}});JPanel top = new JPanel(new FlowLayout());top.add(tfSend);top.add(btSend);top.add(btStart);this.add(top, BorderLayout.SOUTH);final JScrollPane sp = new JScrollPane();sp.setVerticalScrollBarPolicy(JScrollPane.VERTICAL_SCROLLBAR_A LW AYS);sp.setViewportView(this.taShow);this.taShow.setEditable(false);this.add(sp, BorderLayout.CENTER);this.setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE);this.setSize(400, 300);this.setLocation(100, 200);this.setVisible(true);}}import java.io.BufferedReader;import java.io.IOException;import java.io.PrintWriter;import .ServerSocket;import .Socket;import java.util.ArrayList;/*这个类是服务器端的等待客户端连接*/ public class Server extends Thread {ServerUI ui;ServerSocket ss;BufferedReader reader;PrintWriter writer;public Server(ServerUI ui) {this.ui = ui;this.start();}public void run() {try {ss = new ServerSocket(1228);ui.clients=new ArrayList<Socket>();println("启动服务器成功:端口1228");while (true) {println("等待客户端");Socket client = ss.accept();ui.clients.add(client);println("连接成功" + client.toString());new ListenerClient(ui, client);}} catch (IOException e) {println("启动服务器失败:端口1228");println(e.toString());e.printStackTrace();}}public synchronized void sendMsg(String msg) {try {for (int i = 0; i < ui.clients.size(); i++) {Socket client = ui.clients.get(i);writer = new PrintWriter(client.getOutputStream(),true);writer.println(msg);}} catch (Exception e) {println(e.toString());}}public void println(String s) {if (s != null) {this.ui.taShow.setText(this.ui.taShow.getText() + s + "\n");System.out.println(s + "\n");}}public void closeServer() {try {if (ss != null)ss.close();if (reader != null)reader.close();if (writer != null)writer.close();} catch (IOException e) {// TODO Auto-generated catch blocke.printStackTrace();}}}import java.io.BufferedReader;import java.io.IOException;import java.io.InputStreamReader;import java.io.PrintWriter;import .Socket;/*这个类是服务器端的等待客户端发送信息*/public class ListenerClient extends Thread {BufferedReader reader;PrintWriter writer;ServerUI ui;Socket client;public ListenerClient(ServerUI ui, Socket client) {this.ui = ui;this.client=client;this.start();}//为每一个客户端创建线程等待接收信息,然后把信息广播出去public void run() {String msg = "";while (true) {try {reader = new BufferedReader(new InputStreamReader(client.getInputStream()));writer = new PrintWriter(client.getOutputStream(), true);msg = reader.readLine();sendMsg(msg);} catch (IOException e) {println(e.toString());// e.printStackTrace();break;}if (msg != null && msg.trim() != "") {println(">>" + msg);}}}//把信息广播到所有用户public synchronized void sendMsg(String msg) {try {for (int i = 0; i < ui.clients.size(); i++) {Socket client = ui.clients.get(i);writer = new PrintWriter(client.getOutputStream(), true);writer.println(msg);}} catch (Exception e) {println(e.toString());}}public void println(String s) {if (s != null) {this.ui.taShow.setText(this.ui.taShow.getText() + s + "\n");System.out.println(s + "\n");}}}客户端源码:import java.awt.BorderLayout;import java.awt.FlowLayout;import java.awt.event.ActionEvent;import java.awt.event.ActionListener; import java.awt.event.WindowAdapter; import java.awt.event.WindowEvent;import javax.swing.JButton;import javax.swing.JFrame;import javax.swing.JOptionPane;import javax.swing.JPanel;import javax.swing.JScrollPane;import javax.swing.JTextArea;import javax.swing.JTextField;public class ClientUI extends JFrame {public static void main(String[] args) {ClientUI client = new ClientUI();}public ClientUI() {super("客户端");btStart = new JButton("启动连接");btSend = new JButton("发送信息");tfSend = new JTextField(10);tfIP = new JTextField(10);tfPost = new JTextField(5);taShow = new JTextArea();btStart.addActionListener(new ActionListener() {public void actionPerformed(ActionEvent e) {server = new ClientThread(ClientUI.this);}});btSend.addActionListener(new ActionListener() {public void actionPerformed(ActionEvent e) {server.sendMsg(tfSend.getText());tfSend.setText("");}});this.addWindowListener(new WindowAdapter() {public void windowClosing(WindowEvent e) {int a = JOptionPane.showConfirmDialog(null, "确定关闭吗?", "温馨提示",JOptionPane.YES_NO_OPTION);if (a == 1) {System.exit(0); // 关闭}}});JPanel top = new JPanel(new FlowLayout());top.add(tfSend);top.add(btSend);top.add(btStart);this.add(top, BorderLayout.SOUTH);final JScrollPane sp = new JScrollPane();sp.setVerticalScrollBarPolicy(JScrollPane.VERTICAL_SCROLLBAR_A LW AYS);sp.setViewportView(this.taShow);this.taShow.setEditable(false);this.add(sp, BorderLayout.CENTER);this.setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE);this.setSize(400, 300);this.setLocation(600, 200);this.setVisible(true);}public JButton btStart;public JButton btSend;public JTextField tfSend;public JTextField tfIP;public JTextField tfPost;public JTextArea taShow;public ClientThread server}import java.io.BufferedReader;import java.io.IOException;import java.io.InputStreamReader;import java.io.PrintWriter;import .Socket;public class ClientThread extends Thread {ClientUI ui;Socket client;BufferedReader reader;PrintWriter writer;public ClientThread(ClientUI ui) {this.ui = ui;try {client = new Socket("127.0.0.1", 1228);//这里设置连接服务器端的IP的端口println("连接服务器成功:端口1228");reader = new BufferedReader(new InputStreamReader(client.getInputStream()));writer = new PrintWriter(client.getOutputStream(), true);// 如果为true,则println、printf 或format 方法将刷新输出缓冲区} catch (IOException e) {println("连接服务器失败:端口1228");println(e.toString());e.printStackTrace();}this.start();}public void run() {String msg = "";while (true) {try {msg = reader.readLine();} catch (IOException e) {println("服务器断开连接");break;}if (msg != null && msg.trim() != "") {println(">>" + msg);}}}public void sendMsg(String msg) {try {writer.println(msg);} catch (Exception e) {println(e.toString());}}public void println(String s) {if (s != null) {this.ui.taShow.setText(this.ui.taShow.getText() + s + "\n");System.out.println(s + "\n");}}}。