网络编程聊天室主要代码
C#.net聊天室制作代码
2012-2-6聊天室制作流程:建立发送页面send.aspx,显示页面showmessage.aspx,主要是这两个,还可以加显示所以用户名字exit.aspx;思路:聊天室要用到数据库,所以在发送页面需要做的是把用户填好的东西加入到数据库储存起来。
到显示页面和显示所以用户页面就顺理成章的把数据库用户填写的信息读取出来这就构成了一个聊天室的主要骨架。
第一个发送页面send.aspx前台代码:<body><form id="form1"runat="server"><div></div><br/><table align="center"width="600"height="150"><tr><td><strong><span style="color: #ff00ff">内容:</span></strong></td><td><asp:TextBox ID="TextBoxContent"Width="302px"Height="50"runat="server"></asp:TextBox> <asp:Button ID="ButtonSpeak"runat="server"Text="发言"Width="72px"></asp:Button><asp:Button ID="ButtonExit"runat="server"Text="离开"Width="64px"Height="23px"></asp:Button><asp:DropDownList ID="DropDownListColor"runat="server"><asp:ListItem Value="black"Selected="True">黑色</asp:ListItem><asp:ListItem Value="red">红色</asp:ListItem><asp:ListItem Value="blue">蓝色</asp:ListItem><asp:ListItem Value="green">绿色</asp:ListItem></asp:DropDownList><asp:DropDownList ID="DropDownListEmotion"runat="server"><asp:ListItem Value="微笑着">微笑着</asp:ListItem><asp:ListItem Value="无奈地">无奈地</asp:ListItem><asp:ListItem Value="哭丧着脸">哭丧着脸</asp:ListItem> </asp:DropDownList></td></tr></table></form></body>后台:send.aspx.csusing System;using System.Data;using System.Configuration;using System.Web;using System.Web.Security;using System.Web.UI;using System.Web.UI.WebControls;using System.Web.UI.WebControls.WebParts;using System.Web.UI.HtmlControls;using System.Data.SqlClient;public partial class_Default : System.Web.UI.Page{protected void Page_Load(object sender, EventArgs e){}public DBConnection conn = new DBConnection();protected void ButtonSpeak_Click(object sender, EventArgs e){SqlConnection connection = new SqlConnection(ConfigurationSettings.AppSettings["ConnStr"]);connection.Open();string createTime = System.DateTime.Now.ToString();//发言时间string content = TextBoxContent.Text; //发言内容string color = DropDownListColor.SelectedItem.Value; //颜色string emotion = DropDownListEmotion.SelectedItem.Value; //表情string sql;//SqlCommand cmd = new SqlCommand(sql, connection);//SqlDataReader dr = conn.ExecuteReader(sql);sql = "Insert into message(username,createtime,content1,color,emotion) values('"+ Session["username"]+ "','" + createTime+ "','" +content + "','" + color + "','" + emotion + "')";conn.Updata(sql);TextBoxContent.Text="";}protected void ButtonExit_Click(object sender, EventArgs e){Session["username"] = null;Response.Redirect("re.aspx");}}截图:--------------------------------------------------------------------------------------------------------------------------------------------------说明:这里因为要用到数据库sql 所以在开头加上命名空间:using System.Data.SqlClient;还有链接数据库的web.config 文件Web 。
聊天室程序代码---服务器端
int len;
char buf[MAXBUF + 1];
fd_set rfds;
struct timeval tv;
int retval, maxfd = -1;
while (1)
{
FD_ZERO(&rfds);
FD_SET(0, &rfds);
聊天室程序代码服务器端服务器端服务器源代码聊天室聊天程序服务端
#include <stdio.h>
#include <stdlib.h>
#include <errno.h>
#include <string.h>
#include <sys/types.h>
#include <netinet/in.h>
{
perror("bind");
exit(1);
}
if (listen(*sockfd, lisnum) == -1)
{
perror("listen");
exit(1);
}
}
void *pthread_proc(void *arg)
{
SERVER_t *client=(SERVER_t *)arg;
return NULL;
if(*count==0&&head==NULL)
{
(*count)++;
head=p;
p->next=NULL;
return head;
}
else if(*count>0 && head != NULL)
C语言实现简易网络聊天室
C语⾔实现简易⽹络聊天室本⽂实例为⼤家分享了C语⾔实现⽹络聊天室的具体代码,供⼤家参考,具体内容如下业务逻辑:1、客户端注册名字2、告诉所有在线的客户端,XXX进⼊聊天室3、新建⼀个线程为该客户端服务,随时接收客户端发送来的消息4、当接收到⼀个客户端的消息时,向每⼀个客户端转发⼀份(群聊)5、同时在线⼈数最多50⼈任何客户端可以随意随时进⼊或退出客户端服务端代码server.c#include <stdio.h>#include <stdlib.h>#include <string.h>#include <unistd.h>#include <signal.h>#include <pthread.h>#include <semaphore.h>#include <sys/socket.h>#include <netinet/in.h>#include <arpa/inet.h>#ifndef DEBUG#define debug(format,...) {}#else#define debug(format,...) \{\fprintf(stdout,"%s:%d:%s ",__func__,__LINE__,__TIME__);\fprintf(stdout,format,##__VA_ARGS__);\fprintf(stdout,"\n");\}#endif//DEBUG#define error(format,...)\{\fprintf(stdout,"%s:%d:%s ",__func__,__LINE__,__TIME__);\fprintf(stdout,format,##__VA_ARGS__);\fprintf(stdout,":%m\n");\exit(EXIT_FAILURE);\}// 客户端最⼤连接数#define CLIENT_MAX 50// 服务器端⼝号#define PORT 5566// 缓冲区⼤⼩#define BUF_SIZE 4096// 重定义socket地址类型typedef struct sockaddr* SP;// 客户端结构体typedef struct Client{int sock;//socket 标识符pthread_t tid; //线程IDchar name[20];struct sockaddr_in addr;}Client;// 定义50个存储客户端的结构变量Client clients[50];// 定义信号量⽤于限制客户端的数量sem_t sem;// 信号处理函数void sigint(int num){for(int i=0; i<10; i++){if(clients[i].sock){pthread_cancel(clients[i].tid);//销毁线程}}debug("服务器退出!");exit(EXIT_SUCCESS);}void client_eixt(Client* client){sem_post(&sem);close(client->sock);client->sock = 0;}void client_send(Client* client,char* buf){size_t len = strlen(buf)+1;for(int i=0; i<CLIENT_MAX; i++){if(clients[i].sock && clients[i].sock != client->sock) {send(clients[i].sock,buf,len,0);}}}void* run(void* arg){Client* client = arg;char buf[BUF_SIZE] = {};// 接收昵称int ret_size = recv(client->sock,client->name,20,0); if(0 >= ret_size){client_eixt(client);return NULL;}// 通知其它客户端新⼈上线sprintf(buf,"欢迎%s进⼊聊天室",client->name); client_send(client,buf);for(;;){// 接收消息ret_size = recv(client->sock,buf,BUF_SIZE,0);if(0 >= ret_size || 0 == strcmp("quit",buf)){// 通知其它客户端退出sprintf(buf,"%s退出聊天室",client->name);client_send(client,buf);client_eixt(client);return NULL;}strcat(buf,":");strcat(buf,client->name);client_send(client,buf);debug(buf);}}int main(int argc,const char* argv[]){signal(SIGINT,sigint);debug("注册信号处理函数成功!");sem_init(&sem,0,CLIENT_MAX);debug("初始化信号量成功!");int svr_sock = socket(AF_INET,SOCK_STREAM,0);if(0 > svr_sock){error("socket");}debug("创建socket对象成功!");struct sockaddr_in svr_addr = {};svr_addr.sin_family = AF_INET;svr_addr.sin_port = htons(PORT);svr_addr.sin_addr.s_addr = INADDR_ANY;socklen_t addrlen = sizeof(svr_addr);debug("准备通信地址成功!");if(bind(svr_sock,(SP)&svr_addr,addrlen)){error("bind");}debug("绑定socket对象和通信地址成功!");if(listen(svr_sock,10)){error("listen");}debug("设置监听socket监听成功!");for(;;){debug("等待客户端连接...");sem_wait(&sem);int index = 0;while(clients[index].sock){index++;}clients[index].sock = accept(svr_sock,(SP)&clients[index].addr,&addrlen);if(0 > clients[index].sock){kill(getpid(),SIGINT);}debug("有新的客户端连接,from ip:%s",inet_ntoa(clients[index].addr.sin_addr)); pthread_create(&clients[index].tid,NULL,run,&clients[index]);}}客户端代码client.c#include <stdio.h>#include <stdlib.h>#include <string.h>#include <unistd.h>#include <signal.h>#include <pthread.h>#include <semaphore.h>#include <sys/socket.h>#include <netinet/in.h>#include <arpa/inet.h>#ifndef DEBUG#define debug(format,...) {}#else#define debug(format,...) \{\fprintf(stdout,"%s:%d:%s ",__func__,__LINE__,__TIME__);\fprintf(stdout,format,##__VA_ARGS__);\fprintf(stdout,"\n");\}#endif//DEBUG#define error(format,...)\{\fprintf(stdout,"%s:%d:%s ",__func__,__LINE__,__TIME__);\fprintf(stdout,format,##__VA_ARGS__);\fprintf(stdout,":%m\n");\exit(EXIT_FAILURE);\}#define BUF_SIZE 4096#define SERVER_PORT 5566#define SERVER_IP "192.168.0.125"typedef struct sockaddr* SP;void* run(void* arg){int cli_sock = *(int*)arg;char buf[BUF_SIZE] = {};for(;;){int ret_size = recv(cli_sock,buf,BUF_SIZE,0);if(0 >= ret_size){printf("服务器正在升级,请稍候登录!\n");exit(EXIT_SUCCESS);}printf("\r%30s\n>>>",buf);fflush(stdout);}}int main(int argc,const char* argv[]){int cli_sock = socket(AF_INET,SOCK_STREAM,0);if(0 > cli_sock){error("socket");}struct sockaddr_in cli_addr = {};cli_addr.sin_family = AF_INET;cli_addr.sin_port = htons(SERVER_PORT);cli_addr.sin_addr.s_addr = inet_addr(SERVER_IP);socklen_t addrlen = sizeof(cli_addr);if(connect(cli_sock,(SP)&cli_addr,addrlen)){printf("服务器正在升级,请稍候登录!\n");return EXIT_SUCCESS;}char buf[BUF_SIZE] = {};printf("请输⼊你的眤称:");gets(buf);send(cli_sock,buf,strlen(buf)+1,0);pthread_t tid;pthread_create(&tid,NULL,run,&cli_sock);for(;;){printf(">>>");gets(buf);send(cli_sock,buf,strlen(buf)+1,0);if(0 == strcmp("quit",buf)){printf("退出聊天室!\n");return EXIT_SUCCESS;}}}以上就是本⽂的全部内容,希望对⼤家的学习有所帮助,也希望⼤家多多⽀持。
编写程序实现一个简单的聊天室
1、编写程序实现一个简单的聊天室,要能显示发言人姓名、发言内容、发言人IP地址和发言时间。
(1)<html><frameset rows="*,60"><frame name="message" src="4.3.asp"><frame name="say" src="4.2.asp" ></frameset></html>(2)<html><body><form name="form1" method="post" action="">昵称:<input type="text" name="txtname" size="10" />发言:<input type="text" name="txtsay" size="50" /><input type="submit" value="发送" /></form><%if trim(request.Form("txtname "))<>""and trim(request.Form("txtsay"))<>"" then dim strsaystrsay=request.Form("txtname")&"说:"&request.Form("txtsay")&"<br>"application.Lockapplication("strchat")=strsay & application("strchat")application.UnLockend if%></body></html>(3) <html><head><title>显示发言页面</title><meta http-equiv="refresh" content="5" /></head><body><%response.Write application("strchat")%></body></html>2、开发一个简单的在线考试程序,包括5道单选题和5到多选题,单击“交卷”按钮后就可以根据标准答案在线评分。
java聊天室部分主要代码
ChatClient.javaimport java.awt.*;import java.io.*;import .*;import java.applet.*;import java.util.Hashtable;public class ChatClient extends Applet implements Runnable{ Socket socket=null;DataInputStream in=null;//读取服务器端发来的消息DataOutputStream out=null;//向服务器端发送的消息InputInfo 用户名提交界面=null;UserChat 聊天界面=null;Hashtable listTable;//用于存放在线用户的用户名的散列表Label 提示条;Panel north,center;Thread thread;public void init(){setSize(1000,800);int width=getSize().width;int height=getSize().height;listTable=new Hashtable();setLayout(new BorderLayout());用户名提交界面=new InputInfo(listTable);int h=用户名提交界面.getSize().height;聊天界面=new UserChat("",listTable,width,height-(h+5));聊天界面.setVisible(false);提示条=new Label("正在连接到服务器...",Label.CENTER);提示条.setForeground(Color.red);north=new Panel(new FlowLayout(FlowLayout.LEFT));center=new Panel();north.add(用户名提交界面);north.add(提示条);center.add(聊天界面);add(north,BorderLayout.NORTH);add(center,BorderLayout.CENTER);validate();}public void start(){if(socket!=null&&in!=null&&out!=null){try{socket.close();in.close();out.close();聊天界面.setVisible(false);}catch(Exception ee){}}try{socket=new Socket(this.getCodeBase().getHost(),6666);in=new DataInputStream(socket.getInputStream());out=new DataOutputStream(socket.getOutputStream());}catch(IOException ee){提示条.setText("连接失败");}//客户端成功连接服务器端if(socket!=null){InetAddress address=socket.getInetAddress();提示条.setText("连接:"+address+"成功");用户名提交界面.setSocketConnection(socket,in,out);north.validate();}if(thread==null){thread=new Thread(this);thread.start();}}public void stop(){try{socket.close();thread=null;}catch(IOException e){this.showStatus(e.toString());}}public void run(){while(thread!=null){if(用户名提交界面.getchatornot()==true){聊天界面.setVisible(true);聊天界面.setName(用户名提交界面.getName());聊天界面.setSocketConnection(socket,in,out);提示条.setText("祝聊天快乐!");center.validate();break;}try{Thread.sleep(100);}catch(Exception e){}}}}ChatMain.javaimport .*;import java.util.*;public class ChatMain {public static void main(String args[]) {ServerSocket server=null;Socket you=null;Hashtable peopleList;peopleList=new Hashtable();while(true){try{//服务器端在端口6666处监听来自客户端的信息server=new ServerSocket(6666);}catch(IOException e1){System.out.println("正在监听");}try{//当服务器端接收到客户端的消息后,取得客户端的IP地址。
java聊天程序代码
import java.awt.*;import java.awt.event.*;import javax.swing.*;import java.io.*;public class ChatJFrame extends JFrame implements ActionListener {private JTextArea text_receiver; //显示对话内容的文本区private JTextField text_sender; //输入发送内容的文本行private PrintWriter cout; //字符输出流对象private String name; //网名public ChatJFrame(String name, String title, PrintWriter cout) //构造方法{super("聊天室"+name+" "+title);this.setSize(320,240);this.setLocation(300,240);this.setDefaultCloseOperation(EXIT_ON_CLOSE);this.text_receiver = new JTextArea();this.text_receiver.setEditable(false); //不可编辑this.add(this.text_receiver);JPanel panel = new JPanel();this.add(panel,"South");this.text_sender = new JTextField(12);panel.add(this.text_sender);this.text_sender.addActionListener(this); //注册单击事件监听器JButton button_send = new JButton("发送");panel.add(button_send);button_send.addActionListener(this);JButton button_leave = new JButton("离线");panel.add(button_leave);button_leave.addActionListener(this);this.setVisible(true);this.setWriter(cout); = name;}public ChatJFrame(){this("","",null);}public void setWriter(PrintWriter cout) //设置字符输出流对象{this.cout = cout;}public void receive(String message) //显示对方发来的内容{text_receiver.append(message+"\r\n");}public void actionPerformed(ActionEvent e){if (e.getActionCommand()=="离线"){if (this.cout!=null){this.cout.println(name+"离线");this.cout.println("bye");this.cout = null;}text_receiver.append("我离线\n");}else //发送{if (this.cout!=null){this.cout.println(name+" 说:"+text_sender.getText());text_receiver.append("我说:"+text_sender.getText()+"\n"); text_sender.setText("");}elsetext_receiver.append("已离线,不能再发送。
java实现聊天室功能(包含全部代码-有界面)
服务器端代码:import .*;import .*;import .*;import .*;public class Server{private static final int PORT=6666;G_Menu gm=new G_Menu();private ServerSocket server;public ArrayList<PrintWriter> list;public static String user;public static ArrayList<User> list1=new ArrayList<User>();....");while(true){Socket client=();etServer();}class Chat implements Runnable{Socket socket;private BufferedReader br;private String msg;private String mssg="";public Chat(Socket socket){try{=socket;}catch(Exception ex){();}}public void run(){try{br=new BufferedReader(new InputStreamReader()));while((msg=())!=null){if("1008611"))plit(":");quals()+"("+()+")"))etOutputStream());quals ()))etOutputStream());quals(si[0]))lose();;import .*;import .*;import class Socket_one;import .*;import .*;import Landen extends Frame implements ActionListener {JFrame jf=new JFrame("聊天登陆");JPanel jp1=new JPanel();JPanel jp2=new JPanel();JPanel jp3=new JPanel();JPanel jp4=new JPanel();JLabel jl1=new JLabel("姓名:");JLabel jl2=new JLabel("地址:");JLabel jl3=new JLabel("端口:");JRadioButton jrb1=new JRadioButton("男生"); JRadioButton jrb2=new JRadioButton("女生"); JRadioButton jrb3=new JRadioButton("保密");public JTextField jtf1=new JTextField(10);public JTextField jtf2=new JTextField(10);public JTextField jtf3=new JTextField(10);JButton jb1=new JButton("连接");JButton jb2=new JButton("断开");TitledBorder tb=new TitledBorder("");ButtonGroup gb=new ButtonGroup();public void init()quals("断开")){(0);}if().equals("连接")){if().equals("")){(null,"请输入用户名!");}else if(!()&&!()&&!()){(null,"请选择性别!");}else{(false);if()){s1="boy";}else if()){s1="girl";}else if()){s1="secret";}G_Menu gmu=new G_Menu();(),s1);();}}}}public class Login{public static void main(String[] args) {new Landen().init();}}主界面代码:import .*;import .*;import .*;import .*;class G_Menu extends JFrame implements ActionListener {JFrame jf=new JFrame("聊天室");public Socket_one soc;public PrintWriter pw;public JPanel jp1=new JPanel();public JPanel jp2=new JPanel();public JPanel jp3=new JPanel();public JPanel jp4=new JPanel();public JPanel jp5=new JPanel();public JPanel jp6=new JPanel();public JPanel jp7=new JPanel();public static JTextArea jta1=new JTextArea(12,42); public static JTextArea jta2=new JTextArea(12,42);public JLabel jl1=new JLabel("对");public static JComboBox jcomb=new JComboBox();public JCheckBox jcb=new JCheckBox("私聊");public JTextField jtf=new JTextField(36);public JButton jb1=new JButton("发送>>");public JButton jb2=new JButton("刷新");public static DefaultListModel listModel1;public static JList lst1;public String na;public String se;public String message;public void getMenu(String name,String sex)quals("发送>>"))quals("")) {if()){String name1=(String)();message="悄悄话"+na+"("+se+")"+"对"+name1+"说:"+();("4");quals("刷新"));import .*;import .*;class User{private String name;//用户姓名private String sex;//用户性别private Socket sock;//用户自己的socketpublic User(String name,String sex,Socket sock){setName(name);setSex(sex);setSock(sock);}public String getName(){return name;}public void setName(String name){=name;}public String getSex(){return sex;}public void setSex(String sex){=sex;}public Socket getSock(){return sock;}public void setSock(Socket sock){=sock;}}使用说明:1、先将所有的类都编译一下2、先运行服务器端代码3、再运行登录界面代码。
网络编程作业聊天室代码
while(! serverSocket.isClosed()) {
try {
Socket socket = serverSocket.accept(); //不停的接收请求
}
}
public static void main(String[] args) {
new ChatServer();
}
public void removeClient(ChatThread client) {
package name.zrl;
import java.awt.BorderLayout;
import java.awt.event.ActionEvent;
import java.awt.event.ActionListener;
import java.io.IOException;
import .ServerSocket;
import .Socket;
import java.util.ArrayList;
import java.ut javax.swing.JButton;
break;
}
}
}
}).start();
}
}
public void sendMessage(String msg) {
for(ChatThread client : clients) {
client.sendMessage(msg);
JButton jbStart = new JButton("启动服务器");
JLabel jl = new JLabel("服务器的监听端口为8000");
聊天室代码(C#)
C#聊天室代码客户端代码:using System;using System.Collections.Generic;using ponentModel;using System.Data;using System.Drawing;using System.Text;using ;using .Sockets;using System.Windows.Forms;namespace EasyChat{public partial class login_frm : Form{///<summary>/// IP地址///</summary>private IPAddress _ipAddr;#region登录窗体构造函数///<summary>///构造函数,自动生成///</summary>public login_frm(){InitializeComponent();}#endregion#region登录窗体的私有方法///<summary>///验证登录信息///</summary>///<returns>验证结果</returns>private bool ValidateInfo(){if (user_tb.Text.Trim() == string.Empty){MessageBox.Show("请填写用户名!","提示",MessageBoxButtons.OK,rmation);return false;}if (!IPAddress.TryParse(svrip_tb.Text, out _ipAddr)){MessageBox.Show("IP地址不合法!","提示",MessageBoxButtons.OK,rmation);return false;}int _port;if (!int.TryParse(svrport_tb.Text, out _port)){MessageBox.Show("端口号不合法!","提示",MessageBoxButtons.OK,rmation);return false;}else{if (_port < 1024 || _port > 65535){MessageBox.Show("端口号不合法!","提示",MessageBoxButtons.OK,rmation);return false;}}return true;}///<summary>///取消,关闭窗体///</summary>///<param name="sender"></param>///<param name="e"></param>private void cancel_btn_Click(object sender, EventArgs e){this.Close();}///<summary>///登录///</summary>///<param name="sender"></param>///<param name="e"></param>private void login_btn_Click(object sender, EventArgs e){//验证数据合法性if (!ValidateInfo()){return;}int port = int.Parse(svrport_tb.Text);//向服务器发出连接请求TCPConnection conn = new TCPConnection(_ipAddr, port);TcpClient _tcpc = conn.Connect();if (_tcpc == null){MessageBox.Show("无法连接到服务器,请重试!","错误",MessageBoxButtons.OK,MessageBoxIcon.Exclamation);}else{NetworkStream netstream = _tcpc.GetStream();//提供用于访问网络的基本数据流//向服务器发送用户名以确认身份netstream.Write(Encoding.Unicode.GetBytes(user_tb.Text), 0, Encoding.Unicode.GetBytes(user_tb.Text).Length);//得到登录结果byte[] buffer = new byte[50];netstream.Read(buffer, 0, buffer.Length);//该方法将数据读入 buffer 参数并返回成功读取的字节数。
JavaWebSocket实现网络聊天室(群聊+私聊)
JavaWebSocket实现⽹络聊天室(群聊+私聊)1、简单说明谢谢博主的⽂章和项⽬,我是抱着学习的态度,若有理解错的地⽅,请指正。
2、项⽬内容项⽬的功能说明去原博主博客看吧,项⽬上改进的地⽅,我具体做以下说明。
(1)webSocket服务对于webSocket服务代码,我进⾏⼀部分的封装和优化,主要是消息内容的封装、⽤户信息封装。
页⾯显⽰⽤户的昵称,指定⽤户昵称进⾏消息发送。
ChatServer.javapackage q.webSocket;import er;import monDate;import net.sf.json.JSONObject;import org.apache.log4j.Logger;import javax.servlet.http.HttpSession;import javax.websocket.*;import javax.websocket.server.PathParam;import javax.websocket.server.ServerEndpoint;import java.util.Map;import java.util.concurrent.ConcurrentHashMap;/*** @author ccq* @Description webSocket服务* @date 2017/12/16 17:31*/@ServerEndpoint(value="/chatServer/{userid}", configurator = HttpSessionConfigurator.class)public class ChatServer {private static Logger logger = Logger.getLogger(ChatServer.class);private static int onlineCount = 0; // 记录连接数⽬// Map<⽤户id,⽤户信息>private static Map<String, OnlineUser> onlineUserMap = new ConcurrentHashMap<String, OnlineUser>(); //在线⽤户/*** 连接成功调⽤的⽅法*/@OnOpenpublic void onOpen(@PathParam("userid") String userid , Session session, EndpointConfig config){("[ChatServer] connection : userid = " + userid + " , sessionId = " + session.getId());// 增加⽤户数量addOnlineCount();// 获取当前⽤户的sessionHttpSession httpSession = (HttpSession) config.getUserProperties().get(HttpSession.class.getName());User user = (User) httpSession.getAttribute("user"); // 获得当前⽤户信息// 将当前⽤户存到在线⽤户列表中OnlineUser onlineUser = new OnlineUser(user.getUserid(),user.getNickname(),session);onlineUserMap.put(user.getUserid(),onlineUser);// 通知所有在线⽤户,当前⽤户上线String content = "[" + CommonDate.getTime24() + " : " + user.getNickname() + "加⼊聊天室,当前在线⼈数为 " + getOnlineCount() + "位" + "]";JSONObject msg = new JSONObject();msg.put("content",content);String message = Message.getMessage(msg.toString(),Message.NOTICE,onlineUserMap.values());Message.broadcast(message,onlineUserMap.values());}/*** 连接关闭⽅法*/@OnClosepublic void onClose(@PathParam("userid") String userid,Session session,CloseReason closeReason){("[ChatServer] close : userid = " + userid + " , sessionId = " + session.getId() +" , closeCode = " + closeReason.getCloseCode().getCode() + " , closeReason = " +closeReason.getReasonPhrase());// 减少当前⽤户subOnlienCount();// 移除的⽤户信息OnlineUser removeUser = onlineUserMap.remove(userid);onlineUserMap.remove(userid);// 通知所有在线⽤户,当前⽤户下线String content = "["+ CommonDate.getTime24() + " : " + removeUser.getNickname() + " 离开聊天室,当前在线⼈数为 " + getOnlineCount() + "位" + "]";JSONObject msg = new JSONObject();msg.put("content",content);if(onlineUserMap.size() > 0){String message = Message.getMessage(msg.toString(), Message.NOTICE, onlineUserMap.values());Message.broadcast(message,onlineUserMap.values());}else{("content : ["+ CommonDate.getTime24() + " : " + removeUser.getNickname() + " 离开聊天室,当前在线⼈数为 " + getOnlineCount() + "位" + "]"); }}/*** 接收客户端的message,判断是否有接收⼈⽽选择进⾏⼴播还是指定发送* @param data 客户端发来的消息*/@OnMessagepublic void onMessage(@PathParam("userid") String userid,String data){("[ChatServer] onMessage : userid = " + userid + " , data = " + data);JSONObject messageJson = JSONObject.fromObject(data);JSONObject message = messageJson.optJSONObject("message");String to = message.optString("to");String from = message.optString("from");// 将⽤户id转换为名称to = erIdCastNickName(to);OnlineUser fromUser = onlineUserMap.get(from);String sendMessage = Message.getContent(fromUser,to,message.optString("content"),message.optString("time"));String returnData = Message.getMessage(sendMessage, messageJson.optString("type"),null);if(to == null || to.equals("")){ // 进⾏⼴播Message.broadcast(returnData.toString(),onlineUserMap.values());}else{Message.singleSend(returnData.toString(), onlineUserMap.get(from)); // 发送给⾃⼰String[] useridList = message.optString("to").split(",");for(String id : useridList){if(!id.equals(from)){Message.singleSend(returnData.toString(), onlineUserMap.get(id)); // 分别发送给指定的⽤户}}}}/*** 发⽣错误* @param throwable*/@OnErrorpublic void onError(@PathParam("userid") String userid,Session session,Throwable throwable){("[ChatServer] close : userid = " + userid + " , sessionId = " + session.getId() +" , throwable = " + throwable.getMessage() );}public static int getOnlineCount() {return onlineCount;}public synchronized void addOnlineCount(){onlineCount++;}public synchronized void subOnlienCount(){onlineCount--;}/*** 将⽤户id转换为名称* @param userIds* @return*/private String userIdCastNickName(String userIds){String niceNames = "";if(userIds != null && !userIds.equals("")){String[] useridList = userIds.split(",");String toName = "";for (String id : useridList){toName = toName + onlineUserMap.get(id).getNickname() + ",";}niceNames = toName.substring(0,toName.length() - 1);}return niceNames;}}OnlineUser.javapublic class OnlineUser {private String userid;private String nickname;private Session session;} Message.javapackage q.webSocket;import net.sf.json.JSONArray;import net.sf.json.JSONObject;import mons.collections.CollectionUtils;import org.apache.log4j.Logger;import javax.websocket.Session;import java.io.IOException;import java.util.ArrayList;import java.util.Collection;import java.util.List;/*** @author ccq* @Description 消息类* @date 2017/12/16 19:08*/public class Message {private static Logger logger = Logger.getLogger(Message.class);/*** 消息类型*/public static String NOTICE = "notice"; //通知public static String MESSAGE = "message"; //消息/*** 组装信息返回给前台* @param message 交互信息* @param type 信息类型* @param userList 在线列表* @return** "massage" : {* "from" : "xxx",* "to" : "xxx",* "content" : "xxx",* "time" : "xxxx.xx.xx"* },* "type" : {notice|message},* "list" : {[xx],[xx],[xx]}*/public static String getMessage(String message,String type,Collection<OnlineUser> userList){JSONObject msg = new JSONObject();msg.put("message",message);msg.put("type", type);if(CollectionUtils.isNotEmpty(userList)){List<String> propertys = new ArrayList<String>();propertys.add("session");JSONArray userListArray = JSONArray.fromObject(userList,JsonConfigUtils.getJsonConfig(propertys)); msg.put("list", userListArray);}return msg.toString();}/*** 消息内容* @param fromUser* @param to* @param content* @param time* @return* {* "from" : "xxx",* "to" : "xxx",* "content" : "xxx",* "time" : "xxxx.xx.xx"* }*/public static String getContent(OnlineUser fromUser,String to,String content,String time){JSONObject contentJson = new JSONObject();// 转化为json串时去掉session,⽤户session不能被序列化List<String> propertys = new ArrayList<String>();propertys.add("session");contentJson.put("from",JSONObject.fromObject(fromUser,JsonConfigUtils.getJsonConfig(propertys)));contentJson.put("to",to);contentJson.put("content",content);contentJson.put("time",time);return contentJson.toString();}/*** ⼴播消息* @param message 消息* @param onlineUsers 在线⽤户*/public static void broadcast(String message,Collection<OnlineUser> onlineUsers){/***************************在线⽤户***************************/StringBuffer userStr = new StringBuffer();for(OnlineUser user : onlineUsers){userStr.append(user.getNickname() + ",");}userStr.deleteCharAt(userStr.length()-1);("[broadcast] message = " + message + ", onlineUsers = " + userStr.toString());/***************************在线⽤户***************************/for(OnlineUser user : onlineUsers){try {user.getSession().getBasicRemote().sendText(message);} catch (IOException e) {e.printStackTrace();("消息发送失败!" + e.getMessage());continue;}}}/*** 对特定⽤户发送消息* @param message* @param onlineUser*/public static void singleSend(String message, OnlineUser onlineUser){("[singleSend] message = " + message + ", toUser = " + onlineUser.getNickname());try {onlineUser.getSession().getBasicRemote().sendText(message);} catch (IOException e) {e.printStackTrace();("消息发送失败!" + e.getMessage());}}}(2)⽤户头像上传确实⽐较好⽤,贴⼀下主要代码@RequestMapping(value = "{userid}/upload", method = RequestMethod.POST,produces = "application/json; charset=utf-8")@ResponseBodypublic String updateUserPassword(@PathVariable("userid") String userid,String image,HttpServletRequest request){JSONObject responseJson = new JSONObject();String filePath = "I:\\IDEA2017-02\\img\\";String PicName= UUID.randomUUID().toString()+".png";String header ="data:image";String[] imageArr=image.split(",");if(imageArr[0].contains(header)) {//是img的// 去掉头部image=imageArr[1];// 修改图⽚BASE64Decoder decoder = new BASE64Decoder();try {byte[] decodedBytes = decoder.decodeBuffer(image); // 将字符串格式的image转为⼆进制流(biye[])的decodedBytesString imgFilePath = filePath + PicName; //指定图⽚要存放的位File targetFile = new File(filePath);if(!targetFile.exists()){targetFile.mkdirs();}FileOutputStream out = new FileOutputStream(imgFilePath);//新建⼀个⽂件输出器,并为它指定输出位置imgFilePathout.write(decodedBytes); //利⽤⽂件输出器将⼆进制格式decodedBytes输出out.close();// 修改图⽚User user = userService.getUserById(userid);user.setProfilehead(PicName);int flag = userService.updateUser(user);if(flag > 0){Log log = LogUtil.setLog(userid, CommonDate.getTime24(), WordDefined.LOG_TYPE_UPDATE,WordDefined.LOG_DETAIL_UPDATE_PROFILEHEAD, NetUtil.getIpAddress(request)); logService.insertLog(log);}else{responseJson.put("result","error");responseJson.put("msg","上传失败!");}} catch (IOException e) {e.printStackTrace();}}responseJson.put("result","ok");responseJson.put("msg","上传成功!");responseJson.put("fileUrl","/pic/" + PicName);return responseJson.toString();}3、改进的图⽚4、源码地址(2017-12-17晚更新)由于⼩弟刚学会使⽤github,所以现在才把修改的代码地址放出来。
网络编程聊天室主要代码
聊天室客户端主要代码CSocket.hclass CChat_ClientDlg; //dlg类声明class CCSocket : public CSocket{DECLARE_DYNAMIC(CCSocket); //动态类声明public:CCSocket(CChat_ClientDlg* pDlg); //添加构造函数的入口函数virtual ~CCSocket();CChat_ClientDlg* m_pDlg;//指向对话框的指针变量。
virtual void OnReceive(int nErrorCode); //CSocket类添加的事件响应函数};CSokcet.cpp#include"stdafx.h"#include"Chat_Client.h"#include"CSocket.h"#include"Chat_ClientDlg.h" //自行添加的头文件,调用到dlg类的成员函数。
IMPLEMENT_DYNAMIC(CCSocket,CSocket) //动态类声明// CCSocket构造函数、析构函数CCSocket::CCSocket(CChat_ClientDlg* pDlg){m_pDlg=pDlg; //初始化对话框指针变量}CCSocket::~CCSocket(){m_pDlg=NULL;}// CCSocket 成员函数void CCSocket::OnReceive(int nErrorCode){// TODO: 在此添加专用代码和/或调用基类CSocket::OnReceive(nErrorCode);if(nErrorCode==0) m_pDlg->OnReceive(); //调用对话框类的对应函数}CChat_ClientDlg.h#pragma once#include"afxwin.h"#include"Msg.h" //自行添加的包含头文件#include"CSocket.h" //自行添加的包含头文件class CCSocket; //自行添加的类声明// CChat_ClientDlg 对话框类构造函数、析构函数…………protected:HICON m_hIcon;// 生成的消息映射函数virtual BOOL OnInitDialog();afx_msg void OnSysCommand(UINT nID, LPARAM lParam);afx_msg void OnPaint();afx_msg HCURSOR OnQueryDragIcon();afx_msg void OnBnClickedButtonConnect(); //按钮单击事件响应函数声明afx_msg void OnBnClickedButtonClose();afx_msg void OnBnClickedButtonSend();afx_msg void OnDestroy(); //对话框销毁事件响应函数声明DECLARE_MESSAGE_MAP()public:CString m_strSName; // 服务器名称CString m_strCName; // 客户名称//控件变量UINT m_nPort; // 端口号,即聊天室频道CButton m_btnConnect;CButton m_btnClose;CString m_strMsg;CButton m_btnSend;CListBox m_listMsg;CCSocket* m_pSocket; //套接字指针变量CSocketFile* m_pFile;CArchive* m_pArchiveIn; // 用于输入的CArchive对象指针CArchive* m_pArchiveOut; // 用于输出的CArchive对象指针//成员函数void OnReceive(void);void ReceiveMsg(void);void SendMsg(CString strText , bool st);};Chat_ClientDlg.cpp#include"stdafx.h"#include"Chat_Client.h"#include"Chat_ClientDlg.h"#include"Msg.h" //包含头文件#include"CSocket.h" //包含头文件…………//构造函数,初始化变量CChat_ClientDlg::CChat_ClientDlg(CWnd* pParent /*=NULL*/) : CDialog(CChat_ClientDlg::IDD, pParent), m_strSName(_T("")), m_strCName(_T("")), m_nPort(0), m_strMsg(_T("")){m_hIcon = AfxGetApp()->LoadIcon(IDR_MAINFRAME);//初始化自定义变量m_pSocket=NULL;m_pFile=NULL;m_pArchiveIn=NULL;m_pArchiveOut=NULL;}……BEGIN_MESSAGE_MAP(CChat_ClientDlg, CDialog)ON_WM_SYSCOMMAND()ON_WM_PAINT()ON_WM_QUERYDRAGICON()//}}AFX_MSG_MAPON_BN_CLICKED(IDC_BUTTON_CONNECT,&CChat_ClientDlg::OnBnClickedButtonConnect)ON_BN_CLICKED(IDC_BUTTON_CLOSE,&CChat_ClientDlg::OnBnClickedButtonClose)ON_BN_CLICKED(IDC_BUTTON_SEND,&CChat_ClientDlg::OnBnClickedButtonSend)ON_WM_DESTROY()END_MESSAGE_MAP()// CChat_ClientDlg 消息处理程序BOOL CChat_ClientDlg::OnInitDialog(){…………// TODO: 在此添加额外的初始化代码// 初始化文本框变量,更新对话框m_nPort=8000;m_strSName=_T("localhost");UpdateData(FALSE);return TRUE; // 除非将焦点设置到控件,否则返回TRUE }……void CChat_ClientDlg::OnBnClickedButtonConnect(){// TODO: 在此添加控件通知处理程序代码UpdateData(TRUE);m_pSocket=new CCSocket(this); //创建套接字if(!m_pSocket->Create()){delete m_pSocket; // 错误处理m_pSocket=NULL;AfxMessageBox(_T("套接字创建错误!"));return;}if(!m_pSocket->Connect(m_strSName,m_nPort)){delete m_pSocket; // 错误处理m_pSocket=NULL;AfxMessageBox(_T("无法连接服务器!"));return;}m_pFile=new CSocketFile(m_pSocket);m_pArchiveIn=new CArchive(m_pFile,CArchive::load);m_pArchiveOut=new CArchive(m_pFile,CArchive::store);//调用SendMsg函数,向服务器发送消息,表明该客户机进入聊天室CString strTemp;strTemp=m_strCName+_T("进入聊天室"); //发送的消息设为:“客户名”进入聊天室SendMsg(strTemp,FALSE); //m_bClose设为FALSEGetDlgItem(IDC_EDIT_MSG)->EnableWindow(TRUE);GetDlgItem(IDC_BUTTON_CLOSE)->EnableWindow(TRUE);GetDlgItem(IDC_BUTTON_SEND)->EnableWindow(TRUE);GetDlgItem(IDC_EDIT_CLIENTNAME)->EnableWindow(FALSE);GetDlgItem(IDC_BUTTON_CONNECT)->EnableWindow(FALSE);GetDlgItem(IDC_EDIT_SERVNAME)->EnableWindow(FALSE);GetDlgItem(IDC_EDIT_SERVPORT)->EnableWindow(FALSE);}void CChat_ClientDlg::OnBnClickedButtonClose(){// TODO: 在此添加控件通知处理程序代码CString strTemp;strTemp=m_strCName+_T(":离开聊天室!");SendMsg(strTemp,TRUE); //m_bClose设为TRUE//释放资源delete m_pArchiveOut; //删除用于输出的CArchive对象m_pArchiveOut=NULL;delete m_pArchiveIn; //删除用于输入的CArchive对象m_pArchiveIn=NULL;delete m_pFile;m_pFile=NULL;m_pSocket->Close();delete m_pSocket;m_pSocket=NULL;//清空列表框while(m_listMsg.GetCount()!=0)m_listMsg.DeleteString(0);GetDlgItem(IDC_EDIT_MSG)->EnableWindow(FALSE);GetDlgItem(IDC_BUTTON_CLOSE)->EnableWindow(FALSE);GetDlgItem(IDC_BUTTON_SEND)->EnableWindow(FALSE);GetDlgItem(IDC_EDIT_CLIENTNAME)->EnableWindow(TRUE);GetDlgItem(IDC_BUTTON_CONNECT)->EnableWindow(TRUE);GetDlgItem(IDC_EDIT_SERVNAME)->EnableWindow(TRUE);GetDlgItem(IDC_EDIT_SERVPORT)->EnableWindow(TRUE);}void CChat_ClientDlg::OnBnClickedButtonSend(){// TODO: 在此添加控件通知处理程序代码UpdateData(TRUE); //取用户数据if(!m_strMsg.IsEmpty()){this->SendMsg(m_strCName+_T(":")+m_strMsg,FALSE);m_strMsg=_T("");UpdateData(FALSE);}}void CChat_ClientDlg::OnDestroy() //窗口销毁事件响应函数{CDialog::OnDestroy();// TODO: 在此处添加消息处理程序代码if((m_pSocket!=NULL)&&(m_pFile!=NULL)&&(m_pArchiveOut!=NULL)) {//发送客户机离开聊天室的消息CMsg msg;CString strTemp;strTemp=m_strCName+_T("DDDD:离开聊天室!");this->SendMsg(strTemp,TRUE);}delete m_pArchiveOut; //删除用于输出的CArchive对象m_pArchiveOut=NULL;delete m_pArchiveIn; //删除用于输入的CArchive对象m_pArchiveIn=NULL;delete m_pFile;m_pFile=NULL;delete m_pSocket;m_pSocket=NULL;}//CCSocket套接字调用的函数void CChat_ClientDlg::OnReceive(void){do{ReceiveMsg();if(m_pSocket==NULL) return;}while(!m_pArchiveIn->IsBufferEmpty());}//实际接收数据的函数void CChat_ClientDlg::ReceiveMsg(void){CMsg msg;try{//调用消息对象xuliehua函数,接收消息msg.Serialize(*m_pArchiveIn);m_listMsg.AddString(msg.m_strBuf); //将接收到的消息显示在列表框if(msg.m_bClose==true){delete m_pArchiveOut; //删除用于输出的CArchive对象m_pArchiveOut=NULL;delete m_pArchiveIn; //删除用于输入的CArchive对象m_pArchiveIn=NULL;delete m_pFile;m_pFile=NULL;m_pSocket->Close();delete m_pSocket;m_pSocket=NULL;//清空列表框while(m_listMsg.GetCount()!=0)m_listMsg.DeleteString(0);GetDlgItem(IDC_EDIT_MSG)->EnableWindow(FALSE);GetDlgItem(IDC_BUTTON_CLOSE)->EnableWindow(FALSE);GetDlgItem(IDC_BUTTON_SEND)->EnableWindow(FALSE);GetDlgItem(IDC_EDIT_CLIENTNAME)->EnableWindow(TRUE);GetDlgItem(IDC_BUTTON_CONNECT)->EnableWindow(TRUE);GetDlgItem(IDC_EDIT_SERVNAME)->EnableWindow(TRUE);GetDlgItem(IDC_EDIT_SERVPORT)->EnableWindow(TRUE);}}catch(CFileException& e) //错误处理{//显示处理服务器关闭的消息CString strTemp;strTemp=_T("服务器重置连接!连接关闭!");m_listMsg.AddString(strTemp);msg.m_bClose=TRUE;m_pArchiveOut->Abort();//删除相应对象delete m_pArchiveOut; //删除用于输出的CArchive对象m_pArchiveOut=NULL;delete m_pArchiveIn; //删除用于输入的CArchive对象m_pArchiveIn=NULL;delete m_pFile;m_pFile=NULL;m_pSocket->Close();delete m_pSocket;m_pSocket=NULL;}}//实际向服务器发送数据的函数void CChat_ClientDlg::SendMsg(CString strText , bool st) {if(m_pArchiveOut!=NULL){CMsg msg;//将要发送的信息本文赋值给消息对象的成员变量msg.m_strBuf=strText;msg.m_bClose=st;//调用消息对象的序列化函数,发送消息msg.Serialize(*m_pArchiveOut);//将CArchive对象中的数据强制存储到CSocketfile对象中。
用jsp代码编写的网络聊天室程序
<%@ page contentType="text/html;charset=GBK" import="java.util.*"%> <html><head><title>带自动刷新的简易聊天室</title></head><body><center><%if (request.getProtocol().compareTo("HTTP/1.0") == 0)response.setHeader("Pragma", "no-cache");else if (request.getProtocol().compareTo("HTTP/1.1") == 0)response.setHeader("Cache-Control", "no-cache");response.setDateHeader("Expires", -1);%>当前时间:<%response.setHeader("Refresh","30");request.setCharacterEncoding("GBK");Date d=new Date();out.println(""+ d.toLocaleString());String userName = (String)session.getAttribute("userName");if (userName == null )userName="Guest";String chat = request.getParameter("mychat");String chats = (String)application.getAttribute("chat");if (chat!=null){d=new Date();chat=userName + "(" + d.toLocaleString() + "):" + chat;if (chats==null)chats=chat;elsechats = chats + "<br>" + chat;}if (chats!=null){application.setAttribute("chat", chats);%><table border="2" width="400" bordercolorlight="#FFFFFF" bordercolordark="#000000" cellspacing="0" cellpadding="0"><tr><th>简易聊天室</th></tr><tr><td width="100%"><%= application.getAttribute("chat")%></td></tr></table><%}%><FORM ACTION="chat.jsp" METHOD="post"> //注意本表单提交给当前页面action属性<INPUT TYPE="TEXT" SIZE="30" NAME="mychat" V ALUE="我来了!"><INPUT TYPE="SUBMIT" name="submit" V ALUE="我说一句"></FORM></center></BODY></HTML>。
Python实现网络聊天室的示例代码(支持多人聊天与私聊)
Python实现⽹络聊天室的⽰例代码(⽀持多⼈聊天与私聊)实验名称:⽹络聊天室功能:i. 掌握利⽤Socket进⾏编程的技术ii. 掌握多线程技术,保证双⽅可以同时发送iii. 建⽴聊天⼯具iv. 可以和单⼈聊天v. 可以和多个⼈同时进⾏聊天vi. 使⽤图形界⾯,显⽰双⽅的语录vii. 程序可以在⼀定程度上进⾏错误识别概述实验通过聊天室可以完成单⼈或多⼈之间的聊天通信,功能的实现主要是通过Socket通信来实现。
本次实验采⽤客户端/服务器(C/S)架构模式,通过Python语⾔来编写服务器端与客户端的程序。
运⽤多线程可完成多点对多点的聊天。
服务器端程序主要⽤于接收⽤户信息,消息接收与转发。
客户端程序实现⽤户注册登录,聊天信息显⽰与信息输⼊。
代码解释统计当前在线⼈数,并且将新⽤户加到⽤户列表中。
Serve.py这是服务器对于聊天服务的实现。
通过继承threading.Thread类⽽实现多线程,重写run函数。
接受来⾃客户端的⽤户名,如果⽤户名为空,使⽤⽤户的IP与端⼝作为⽤户名。
如果⽤户名出现重复,则在出现的⽤户名依此加上后缀“2”、“3”、“4”……在获取⽤户名后便会不断地接受⽤户端发来的消息(即聊天内容),结束后关闭连接。
如果⽤户断开连接,将该⽤户从⽤户列表中删除,然后更新⽤户列表。
将地址与数据(需发送给客户端)存⼊messages队列。
服务端在接受到数据后,会对其进⾏⼀些处理然后发送给客户端,如下图,对于聊天内容,服务端直接发送给客户端,⽽对于⽤户列表,便由json.dumps处理后发送。
Client.py建⽴连接,发送⽤户名及判断是否为私聊消息,私聊⽤~识别接受来⾃服务器发送的消息对接收到的消息进⾏判断,如果是在线⽤户列表(⽤json.dumps处理过),便清空在线⽤户列表框,并将此列表输出在在线⽤户列表框中。
如果是聊天内容,便将其输出在聊天内容显⽰框中。
设置登录窗⼝设置消息界⾯设置在线⽤户列表。
C语言聊天室
C语言TCP聊天室代码客户端:#pragma comment(lib,"ws2_32.lib")#include<winsock2.h>#include<stdio.h>#include<string.h>#include<windows.h>#include<PROCESS.H>void _cdecl get_keyboard_input(void * param){SOCKET sock =(SOCKET)param;while(1){char buf[1024];gets(buf);int sByte = send(sock,buf,strlen(buf),0);if(sByte == SOCKET_ERROR){printf("send() failed:%d\n",WSAGetLastError());}}}int main(){WSADA TA wsadata;int err = WSAStartup(WINSOCK_VERSION,&wsadata);if(err != 0){printf("WSAStartup() failed :%d\n",WSAGetLastError());return -1;}SOCKET sock = socket(AF_INET,SOCK_STREAM,0);if(sock == INV ALID_SOCKET){printf("socket() failed:%d\n",WSAGetLastError());WSACleanup();return -1;}sockaddr_in serveraddr;serveraddr.sin_family = AF_INET;serveraddr.sin_port = htons(27015);serveraddr.sin_addr.S_un.S_addr = inet_addr("127.0.0.1");err=connect(sock,(sockaddr *)&serveraddr,sizeof(serveraddr)); if(err == INV ALID_SOCKET){printf("connect() failed:%d\n",WSAGetLastError());closesocket(sock);WSACleanup();return -1;}_beginthread(get_keyboard_input,0,(void*)sock);Sleep(1000);char rbuf[1024];while(1){memset(rbuf,0,1024);int rByte =recv(sock,rbuf,1024,0);if(rByte == SOCKET_ERROR){printf("recv() failed:%d\n",WSAGetLastError());closesocket(sock);WSACleanup();return -1;}if(rByte == 0){printf("Connection is closed.\n");break;}printf("TCP recv DA TA:%s\n",rbuf);Sleep(1000);}WSACleanup();return 0;}服务端:#pragma comment(lib,"ws2_32.lib")#include<winsock2.h>#include<stdio.h>#include<string.h>#define MAX_CLIENT_NUM 63int main(){WSADA TA wsadata;int err = WSAStartup(WINSOCK_VERSION,&wsadata);if(err != 0){printf("WSAStartup() failed :%d\n",WSAGetLastError());return -1;}SOCKET sock = socket(AF_INET,SOCK_STREAM,0);if(sock == INV ALID_SOCKET){printf("socket() failed:%d\n",WSAGetLastError());WSACleanup();return -1;}sockaddr_in localaddr;localaddr.sin_family = AF_INET;localaddr.sin_port = htons(27015);localaddr.sin_addr.S_un.S_addr = htonl(INADDR_ANY);err = bind(sock,(sockaddr *)&localaddr,sizeof(localaddr));if(err == INV ALID_SOCKET){printf("bind() failed:%d\n",WSAGetLastError());closesocket(sock);WSACleanup();return -1;}if(err == INV ALID_SOCKET){printf("listen() failed:%d\n",WSAGetLastError());closesocket(sock);WSACleanup();return -1;}SOCKET client[MAX_CLIENT_NUM];for(int i = 0;i<MAX_CLIENT_NUM;i++){client[i] = INV ALID_SOCKET;}fd_set rset,allset;FD_ZERO(&allset);FD_SET(sock,&allset);#define MSG_MAX_SIZE 1024char buf[MAX_CLIENT_NUM][MSG_MAX_SIZE];while(1){rset = allset;int ret = select(0,&rset,NULL,NULL,NULL);if(ret == SOCKET_ERROR){printf("select() failed:%ld\n",WSAGetLastError());break;}if(ret == 0){continue;}if(FD_ISSET(sock,&rset)){sockaddr_in clientaddr;int len = sizeof(clientaddr);SOCKET sockconn = accept(sock,(sockaddr *)&clientaddr,&len);if(sockconn == INV ALID_SOCKET){printf("accept() failed:%d\n",WSAGetLastError());break;}printf("Client's IP:%s\nClient's Port:%d\n",inet_ntoa(clientaddr.sin_addr),clientaddr.sin_port);for(i=0;i<MAX_CLIENT_NUM;i++){if(client[i] == INV ALID_SOCKET){client[i] = sockconn;break;}}if(i<MAX_CLIENT_NUM){FD_SET(sockconn,&allset);}else{printf("too many client");closesocket(sockconn);}}for(i=0;i<MAX_CLIENT_NUM;i++){if((client[i]!=INV ALID_SOCKET)&&FD_ISSET(client[i],&rset)){memset(buf[i],0,MSG_MAX_SIZE);int rByte = recv(client[i],buf[i],MSG_MAX_SIZE,0);if(rByte == SOCKET_ERROR){printf("recv() failed:%d\n",WSAGetLastError());FD_CLR(client[i],&allset);closesocket(client[i]);client[i] = INV ALID_SOCKET;continue;}if(rByte == 0){printf("Connection is closed. ");FD_CLR(client[i],&allset);closesocket(client[i]);client[i] = INV ALID_SOCKET;continue;}for(int j=0;j<MAX_CLIENT_NUM;j++){if((client[j]!=INV ALID_SOCKET) ){int sByte = send(client[j],buf[i],1024,0);if(sByte == SOCKET_ERROR){printf("send() failed:%d\n",WSAGetLastError());}}}printf("TCP recv[%d]DA TA:%s\n",rByte,buf[i]);}}}closesocket(sock);WSACleanup();return 0;}。
网络聊天室代码
package com.elient;import java.io.DataInputStream;import java.io.DataOutputStream;import java.io.IOException;import .Socket;import .UnknownHostException;import java.util.ArrayList;import java.util.HashMap;import java.util.List;import java.util.Map;public class Client extends Thread{public Socket c_socket ;private Client_chatFrame c_chatFrame;private Client_enterFrame c_enterFrame;private Client_singleFrame c_singleFrame;public DataInputStream dis = null;public DataOutputStream dos = null;private boolean flag_exit = false;private int threadID;public Map<String, Client_singleFrame> c_singleFrames;public List<String> username_online;public List<Integer> clientuserid;public String username = null;public String chat_re;//getter, setter方法public Client_chatFrame getC_chatFrame() {return c_chatFrame;}public Client_singleFrame getC_singlFrame() {return c_singleFrame;}public void setC_singlFrame(Client_singleFrame c_singlFrame) { this.c_singleFrame = c_singlFrame;}public void setC_chatFrame(Client_chatFrame c_chatFrame) { this.c_chatFrame = c_chatFrame;}public Client_enterFrame getC_enterFrame() {return c_enterFrame;}public void setC_enterFrame(Client_enterFrame c_enterFrame) {this.c_enterFrame = c_enterFrame;}public int getThreadID() {return threadID;}public void setThreadID(int threadID) {this.threadID = threadID;}public Client(){c_singleFrames = new HashMap<String, Client_singleFrame>();username_online = new ArrayList<String>();clientuserid = new ArrayList<Integer>();// signlechatuse = new ArrayList<String>();}public static void main(String[] args) {Client client = new Client();Client_enterFrame c_enterFrame = new Client_enterFrame(client);client.setC_enterFrame(c_enterFrame);c_enterFrame.setVisible(true);}public String login(String username, String hostIp, String hostPort) {ername = username;String login_mess = null;try {c_socket = new Socket(hostIp, Integer.parseInt(hostPort));} catch (NumberFormatException e) {login_mess = "连接的服务器端口号port为整数,取值范围为:1024<port<65535";return login_mess;} catch (UnknownHostException e) {login_mess = "主机地址错误";return login_mess;} catch (IOException e) {login_mess = "连接服务其失败,请稍后再试";return login_mess;}return "true";}public void showChatFrame(String username) {getDataInit();c_chatFrame = new Client_chatFrame(this,username);c_chatFrame.setVisible(true);flag_exit = true;this.start();}private void getDataInit() {try {dis = new DataInputStream(c_socket.getInputStream());dos = new DataOutputStream(c_socket.getOutputStream());} catch (IOException e) {e.printStackTrace();}}public void run() {while(flag_exit){try {chat_re = dis.readUTF();} catch (IOException e) {flag_exit = false;if(!chat_re.contains("@serverexit")){chat_re = null;}}if(chat_re != null){if(chat_re.contains("@clientThread")){int local = chat_re.indexOf("@clientThread");setThreadID(Integer.parseInt(chat_re.substring(0, local)));try {dos.writeUTF(username + "@login" + getThreadID() + "@login");} catch (IOException e) {e.printStackTrace();}}else{if(chat_re.contains("@userlist")){c_chatFrame.setDisUsers(chat_re);}else{if(chat_re.contains("@chat")){c_chatFrame.setDisMess(chat_re);}else{if(chat_re.contains("@serverexit")){c_chatFrame.closeClient();}else{if(chat_re.contains("@single")){c_chatFrame.setSingleFrame(chat_re);}}}}}}}}public void transMess(String mess) {try {dos.writeUTF(username + "@chat" + getThreadID() + "@chat"+ mess + "@chat");} catch (IOException e) {e.printStackTrace();}}public void exitChat() {try {dos.writeUTF(username + "@exit" + getThreadID() + "@exit");flag_exit = false;System.exit(0);} catch (IOException e) {e.printStackTrace();}}public void exitLogin() {System.exit(0);}public void exitClient() {flag_exit = false;System.exit(0);}}package com.elient;import java.awt.Font;import java.awt.Toolkit;import java.awt.event.ActionEvent;import java.awt.event.ActionListener;import java.awt.event.KeyEvent;import java.awt.event.KeyListener;import java.awt.event.WindowAdapter;import java.awt.event.WindowEvent;import java.util.ArrayList;import java.util.List;import javax.swing.BorderFactory;import javax.swing.JButton;import javax.swing.JFrame;import javax.swing.JList;import javax.swing.JOptionPane;import javax.swing.JScrollPane;import javax.swing.JTextArea;import javax.swing.JTextField;import javax.swing.ListModel;import javax.swing.ListSelectionModel;import javax.swing.UIManager;import javax.swing.UnsupportedLookAndFeelException;import javax.swing.event.ListSelectionEvent;import javax.swing.event.ListSelectionListener;public class Client_chatFrame extends JFrame implements ActionListener,KeyListener, ListSelectionListener {public Client_chatFrame(Client client, String title) {this.client = client;try {UIManager.setLookAndFeel(UIManager.getSystemLookAndFeelClassName());} catch (ClassNotFoundException e) {e.printStackTrace();} catch (InstantiationException e) {e.printStackTrace();} catch (IllegalAccessException e) {e.printStackTrace();} catch (UnsupportedLookAndFeelException e) {e.printStackTrace();}setIconImage(Toolkit.getDefaultToolkit().getImage("Images/socket.jpg"));setTitle("\u804A\u5929\u5BA4" + " " + title);setSize(450, 325);WinCenter.center(this);setResizable(false);addWindowListener(new WindowAdapter() {@Overridepublic void windowClosing(WindowEvent arg0) {jbt_exit.doClick();}});getContentPane().setLayout(null);JScrollPane scrollPane = new JScrollPane();scrollPane.setBorder(BorderFactory.createTitledBorder("聊天消息")); scrollPane.setBounds(10, 10, 283, 167);scrollPane.setWheelScrollingEnabled(true);getContentPane().add(scrollPane);jta_disMess = new JTextArea();jta_disMess.setEditable(false);scrollPane.setViewportView(jta_disMess);jtf_inputMess = new JTextField();jtf_inputMess.addKeyListener(this);jtf_inputMess.setBounds(10, 242, 192, 32);getContentPane().add(jtf_inputMess);jtf_inputMess.setColumns(10);jbt_trans = new JButton("\u53D1 \u9001");jbt_trans.setFont(new Font("宋体", Font.PLAIN, 14));jbt_trans.setBounds(212, 241, 93, 32);jbt_trans.addActionListener(this);getContentPane().add(jbt_trans);jbt_clear = new JButton("\u6E05\u9664\u804A\u5929\u8BB0\u5F55"); jbt_clear.setFont(new Font("宋体", Font.PLAIN, 14));jbt_clear.setBounds(158, 187, 135, 37);jbt_clear.addActionListener(this);getContentPane().add(jbt_clear);jbt_exit = new JButton("\u9000\u51FA\u804A\u5929\u5BA4");jbt_exit.setFont(new Font("宋体", Font.PLAIN, 14));jbt_exit.setBounds(20, 189, 128, 37);jbt_exit.addActionListener(this);getContentPane().add(jbt_exit);scrollPane_1 = new JScrollPane();scrollPane_1.setBorder(BorderFactory.createTitledBorder("在线用户"));scrollPane_1.setBounds(303, 10, 128, 214);getContentPane().add(scrollPane_1);jlt_disUsers = new JList();jlt_disUsers.setVisibleRowCount(4);jlt_disUsers.setSelectedIndex(0);jlt_disUsers.setSelectionMode(ListSelectionModel.SINGLE_INTERV AL_SELECTION);jlt_disUsers.addListSelectionListener(this);scrollPane_1.setViewportView(jlt_disUsers);jbt_singlChat = new JButton("\u5355\u4EBA\u804A\u5929");jbt_singlChat.setBounds(315, 241, 116, 32);jbt_singlChat.addActionListener(this);getContentPane().add(jbt_singlChat);}/****/private static final long serialVersionUID = 1L;private JTextField jtf_inputMess;private JTextArea jta_disMess;private JButton jbt_trans;private JButton jbt_clear;private JButton jbt_exit;private JList jlt_disUsers;private JButton jbt_singlChat;private JScrollPane scrollPane_1;private Client client;@Overridepublic void actionPerformed(ActionEvent e) {if (e.getSource() == jbt_clear) {jta_disMess.setText("");}if (e.getSource() == jbt_trans) {String mess = jtf_inputMess.getText();mess.trim();jtf_inputMess.setText("");if (mess.equals("")) {JOptionPane.showMessageDialog(this, "不能发送空消息");jtf_inputMess.setText("");} else {client.transMess(mess);}}if (e.getSource() == jbt_exit) {if (JOptionPane.OK_OPTION == JOptionPane.showConfirmDialog(this,"是否确定要退出聊天室?", "提示", JOptionPane.OK_CANCEL_OPTION)) {this.setVisible(false);client.exitChat();System.exit(0);}}if (e.getSource() == jbt_singlChat) {String user_names = (String) jlt_disUsers.getSelectedV alue();if (user_names == null) {JOptionPane.showMessageDialog(this, "您未选择聊天对象\n请选择要单独聊天的对象");} else {if (!client.c_singleFrames.containsKey(user_names)) {createSingleChatFrame(user_names);} else {client.c_singleFrames.get(user_names).setFocusableWindowState(true);}}}}@Overridepublic void keyPressed(KeyEvent arg0) {if (arg0.getKeyCode() == KeyEvent.VK_ENTER) {if (arg0.getSource() == jtf_inputMess) {jbt_trans.doClick();}}}@Overridepublic void keyReleased(KeyEvent arg0) {}@Overridepublic void keyTyped(KeyEvent arg0) {}public void setDisMess(String substring) {int local = substring.indexOf("@chat");jta_disMess.append(substring.substring(0, local) + "\n");jta_disMess.setCaretPosition(jta_disMess.getText().length());}public void setDisUsers(String chat_re) {String[] infos = chat_re.split("@userlist");String[] info = new String[infos.length / 2];for (int i = 1; i < infos.length; i++) {int id_user = 0;try {id_user = Integer.parseInt(infos[i]);if (client.getThreadID() == id_user) {if (!ername.equals(infos[i - 1])) {JOptionPane.showMessageDialog(this,"由于有同名的用户登录,所以您的用户名后面加上了编号");ername = infos[i - 1];this.setTitle("聊天室" + ername);break;} else {break;}} else {i++;}} catch (Exception e) {}}if (infos.length == 2) {String[] s = new String[] {};if (!client.c_singleFrames.isEmpty()) {ListModel list = jlt_disUsers.getModel();for (int i = 0; i < list.getSize(); i++) {if (client.c_singleFrames.get(list.getElementAt(i)) != null) {client.c_singleFrames.get(list.getElementAt(i)).setExitNotify();}}}jlt_disUsers.removeAll();jlt_disUsers.setListData(s);} else {if ((infos.length / 2 - 1) < ername_online.size()) {// 有人下线List<String> rec = new ArrayList<String>();int i = 0;for (; i < infos.length; i++) {rec.add(0, infos[i++]);}for (i = 0; i < ername_online.size(); i++) {if (!rec.contains(ername_online.get(i))) {break;}}String name = ername_online.get(i);ername_online.remove(i);try {client.clientuserid.remove(i);} catch (Exception e) {e.printStackTrace();}if (client.c_singleFrames.containsKey(name)) {client.c_singleFrames.get(name).closeSingleFrame();client.c_singleFrames.remove(name);}} else {List<Integer> online = new ArrayList<Integer>();for (int i = 0; i < ername_online.size(); i++) {online.add(0, client.clientuserid.get(i));}if (online.isEmpty()) {for (int i = 1; i < infos.length; i++) {if ((int) Integer.parseInt(infos[i]) != client.getThreadID()) {ername_online.add(0, infos[i - 1]);client.clientuserid.add(0,Integer.parseInt(infos[i]));}i++;}} else {for (int i = 1; i < infos.length; i++) {if (Integer.parseInt(infos[i]) != client.getThreadID()) {if (!online.contains(Integer.parseInt(infos[i]))) {ername_online.add(0, infos[i - 1]);client.clientuserid.add(0,Integer.parseInt(infos[i]));} else {String name = ername_online.get(client.clientuserid.indexOf(Integer.parseInt(infos[i])));if (!name.equals(infos[i - 1])) {if (client.c_singleFrames.containsKey(name)) {Client_singleFrame cf = client.c_singleFrames.get(name);cf.setTitle(name);client.c_singleFrames.remove(name);client.c_singleFrames.put(name, cf);cf.setVisible(false);}ername_online.remove(name);client.clientuserid.remove(new Integer(Integer.parseInt(infos[i])));ername_online.add(0, infos[i - 1]);client.clientuserid.add(0,Integer.parseInt(infos[i]));}}}i++;}}}try {for (int i = 0; i < ername_online.size(); i++) {info[i] = ername_online.get(i);}} catch (Exception e) {}jlt_disUsers.removeAll();jlt_disUsers.setListData(info);}}public void closeClient() {JOptionPane.showMessageDialog(this, "服务器已关闭", "提示",JOptionPane.OK_OPTION);client.exitClient();setVisible(false);}@Overridepublic void valueChanged(ListSelectionEvent e) {if (e.getSource() == jlt_disUsers) {}}public void createSingleChatFrame(String name) {Client_singleFrame c_singlFrame = new Client_singleFrame(client, name);client.c_singleFrames.put(name, c_singlFrame);try {c_erThreadID = client.clientuserid.get(ername_online.indexOf(name));} catch (Exception e) {}c_singlFrame.setVisible(true);}public void setSingleFrame(String chat_re) {String[] infos = chat_re.split("@single");try {if (client.c_singleFrames.containsKey(infos[0])) {client.c_singleFrames.get(infos[0]).setDisMess(infos[3]);} else {createSingleChatFrame(infos[0]);client.c_singleFrames.get(infos[0]).setDisMess(infos[3]);}} catch (Exception e) {}}}package com.elient;import javax.swing.JFrame;import javax.swing.JLabel;import javax.swing.JOptionPane;import javax.swing.UIManager;import javax.swing.UnsupportedLookAndFeelException;import java.awt.Font;import java.awt.Toolkit;import java.awt.event.ActionEvent;import java.awt.event.ActionListener;import java.awt.event.KeyEvent;import java.awt.event.KeyListener;import java.awt.event.WindowAdapter;import java.awt.event.WindowEvent;import .Inet4Address;import .UnknownHostException;import javax.swing.JTextField;import javax.swing.JButton;public class Client_enterFrame extends JFrame implements ActionListener, KeyListener{ public Client_enterFrame(Client client) {this.client = client;try {UIManager.setLookAndFeel(UIManager.getSystemLookAndFeelClassName());} catch (ClassNotFoundException e1) {e1.printStackTrace();} catch (InstantiationException e1) {e1.printStackTrace();} catch (IllegalAccessException e1) {e1.printStackTrace();} catch (UnsupportedLookAndFeelException e1) {e1.printStackTrace();}setIconImage(Toolkit.getDefaultToolkit().getImage("Images/socket.jpg"));setTitle("\u804A\u5929\u5BA4");getContentPane().setLayout(null);setSize(296, 249);WinCenter.center(this);setResizable(false);addWindowListener(new WindowAdapter() {@Overridepublic void windowClosing(WindowEvent e) {jbt_exit.doClick();}});JLabel lblNewLabel = new JLabel("\u7528\u6237\u540D"); lblNewLabel.setFont(new Font("宋体", Font.PLAIN, 14)); lblNewLabel.setBounds(23, 30, 81, 34);getContentPane().add(lblNewLabel);jtf_username = new JTextField();jtf_username.addKeyListener(this);jtf_username.setBounds(114, 30, 143, 34);getContentPane().add(jtf_username);jtf_username.setColumns(10);JLabel lblNewLabel_1 = new JLabel("\u670D\u52A1\u5668\u5730\u5740"); lblNewLabel_1.setFont(new Font("宋体", Font.PLAIN, 14)); lblNewLabel_1.setBounds(23, 74, 81, 34);getContentPane().add(lblNewLabel_1);jtf_hostIp = new JTextField();jtf_hostIp.setBounds(114, 74, 143, 34);jtf_hostIp.addKeyListener(this);getContentPane().add(jtf_hostIp);try {String ip = (String)Inet4Address.getLocalHost().getHostAddress();jtf_hostIp.setText(ip);} catch (UnknownHostException e) {e.printStackTrace();}jtf_hostIp.setColumns(10);JLabel lblNewLabel_2 = new JLabel("\u7AEF\u53E3\u53F7"); lblNewLabel_2.setFont(new Font("宋体", Font.PLAIN, 14)); lblNewLabel_2.setBounds(23, 118, 81, 34);getContentPane().add(lblNewLabel_2);jtf_hostPort = new JTextField();jtf_hostPort.addKeyListener(this);jtf_hostPort.setBounds(114, 118, 143, 34);getContentPane().add(jtf_hostPort);jtf_hostPort.setText("5000");jtf_hostPort.setColumns(10);jbt_enter = new JButton("\u8FDB\u5165\u804A\u5929\u5BA4");jbt_enter.addActionListener(this);jbt_enter.addKeyListener(this);jbt_enter.setFont(new Font("宋体", Font.PLAIN, 14));jbt_enter.setBounds(23, 162, 108, 39);getContentPane().add(jbt_enter);jbt_exit = new JButton("\u9000\u51FA\u804A\u5929\u5BA4");jbt_exit.setFont(new Font("宋体", Font.PLAIN, 14));jbt_exit.setBounds(144, 162, 113, 39);jbt_exit.addActionListener(this);getContentPane().add(jbt_exit);}/****/private static final long serialVersionUID = 1L;private JTextField jtf_username;private JTextField jtf_hostIp;private JTextField jtf_hostPort;private JButton jbt_enter;private JButton jbt_exit;private Client client;@Overridepublic void actionPerformed(ActionEvent e) {if(e.getSource() == jbt_exit){setVisible(false);client.exitLogin();}if(e.getSource() == jbt_enter){String username = jtf_username.getText();username.trim();String hostIp = jtf_hostIp.getText();hostIp.trim();String hostPort = jtf_hostPort.getText();hostPort.trim();if(!username.equals("")){if(!hostIp.equals("")){if(!hostPort.equals("")){String login_mess = client.login(username, hostIp, hostPort);if(login_mess.equals("true")){this.setVisible(false);client.showChatFrame(username);}else{JOptionPane.showMessageDialog(this, login_mess);}}else{JOptionPane.showMessageDialog(this, "服务器连接端口号不能为空!");}}else{JOptionPane.showMessageDialog(this, "服务器地址不能为空!");}}else{JOptionPane.showMessageDialog(this, "用户名不能为空!");}}}@Overridepublic void keyPressed(KeyEvent arg0) {if(arg0.getKeyCode() == KeyEvent.VK_ENTER){jbt_enter.doClick();}}@Overridepublic void keyReleased(KeyEvent arg0) {}@Overridepublic void keyTyped(KeyEvent arg0) {}}package com.elient;import java.awt.BorderLayout;import ponent;import java.awt.Container;import java.awt.Toolkit;import java.awt.event.ActionEvent;import java.awt.event.ActionListener;import java.awt.event.KeyEvent;import java.awt.event.KeyListener;import java.awt.event.WindowAdapter;import java.awt.event.WindowEvent;import java.io.IOException;import java.text.SimpleDateFormat;import java.util.Date;import javax.swing.BorderFactory;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;import javax.swing.UIManager;import javax.swing.UnsupportedLookAndFeelException;public class Client_singleFrame extends JFrame implements ActionListener, KeyListener{/****/private static final long serialVersionUID = 1L;private static JTextArea jta_disMess;private JTextField jtf_inputMess;private JButton jbt_trans;public int userThreadID = 0;private Client client;public Client_singleFrame(Client client, String title) {this.client = client;init(title);}private void init(String title) {try {UIManager.setLookAndFeel(UIManager.getSystemLookAndFeelClassName());} catch (ClassNotFoundException e1) {e1.printStackTrace();} catch (InstantiationException e1) {e1.printStackTrace();} catch (IllegalAccessException e1) {e1.printStackTrace();} catch (UnsupportedLookAndFeelException e1) {e1.printStackTrace();}setIconImage(Toolkit.getDefaultToolkit().getImage("Images/socket.jpg"));WinCenter.center(this);setTitle(title);setSize(400, 400);setResizable(false);setContentPane(createContentPanel());addWindowListener(new WindowAdapter() {@Overridepublic void windowClosing(WindowEvent e) {closeSingleFrame();}});}private Container createContentPanel() {JPanel jp = new JPanel();jp.setBorder(BorderFactory.createTitledBorder("聊天消息"));jp.setLayout(new BorderLayout());jta_disMess = new JTextArea();jta_disMess.setEditable(false);jp.add(BorderLayout.CENTER, new JScrollPane(jta_disMess));jp.add(BorderLayout.SOUTH, createInput());return jp;}private Component createInput() {JPanel jp = new JPanel();jp.setBorder(BorderFactory.createTitledBorder("发送消息"));jp.setLayout(new BorderLayout());jtf_inputMess = new JTextField();jtf_inputMess.addKeyListener(this);jbt_trans = new JButton("发送");jbt_trans.addActionListener(this);jp.add(jtf_inputMess, BorderLayout.CENTER);jp.add(jbt_trans, BorderLayout.EAST);return jp;}@Overridepublic void keyPressed(KeyEvent arg0) {if(arg0.getKeyCode() == KeyEvent.VK_ENTER){if(arg0.getSource() == jtf_inputMess){jbt_trans.doClick();}}}@Overridepublic void keyReleased(KeyEvent arg0) {}@Overridepublic void keyTyped(KeyEvent arg0) {}@Overridepublic void actionPerformed(ActionEvent e) {if(e.getSource() == jbt_trans){String str = jtf_inputMess.getText();str.trim();jtf_inputMess.setText("");if(str.equals("")){JOptionPane.showMessageDialog(this, "信息不能为空");}else{SimpleDateFormat form = new SimpleDateFormat("yyyy-MM-dd HH:mm");String date = form.format(new Date());String mess = ername + " " + date + "\n" + str;jta_disMess.append(mess + "\n");jta_disMess.setCaretPosition(jta_disMess.getText().length());int index = ername_online.indexOf(this.getTitle());String info = ername + "@single" + client.getThreadID() + "@single" +(int)client.clientuserid.get(index) + "@single" +mess + "@single";try {client.dos.writeUTF(info);} catch (IOException e1) {e1.printStackTrace();}}}}public void setDisMess(String chat_re) {jta_disMess.append(chat_re + "\n");jta_disMess.setCaretPosition(jta_disMess.getText().length());}public void closeSingleFrame(){client.c_singleFrames.remove(this.getTitle());setVisible(false);}public void setExitNotify() {jta_disMess.append(this.getTitle() + "已下线.....");jbt_trans.setEnabled(false);}}package com.elient;import java.awt.Dimension;import java.awt.Toolkit;import java.awt.Window;public class WinCenter {public static void center(Window win){Toolkit tkit = Toolkit.getDefaultToolkit();Dimension sSize = tkit.getScreenSize();Dimension wSize = win.getSize();if(wSize.height > sSize.height){wSize.height = sSize.height;}if(wSize.width > sSize.width){wSize.width = sSize.width;}win.setLocation((sSize.width - wSize.width)/ 2, (sSize.height - wSize.height)/ 2);}}package com.server;public class Server {private ServerFrame serverFrame;private ServerThread serverThread;public ServerFrame getServerFrame() {return serverFrame;}public void setServerFrame(ServerFrame serverFrame) { this.serverFrame = serverFrame;}public Server(){}public void startServer() {try{serverThread = new ServerThread(serverFrame);}catch(Exception e){System.exit(0);}serverThread.setFlag_exit(true);serverThread.start();}public void stopServer(){synchronized (serverThread.messages) {String str = "@serverexit";serverThread.messages.add(str);}serverThread.serverFrame.setDisMess("@exit");serverThread.serverFrame.setDisUsers("@exit");serverThread.stopServer();}public static void main(String[] args) {Server server = new Server();ServerFrame serverFrame = new ServerFrame(server);server.setServerFrame(serverFrame);serverFrame.setVisible(true);}public void close() {if(serverThread != null){if(serverThread.isAlive()){serverThread.stopServer();}}System.exit(0);}}package com.server;import java.io.IOException;public class BroadCast extends Thread {ClientThread clientThread;ServerThread serverThread;String str;private boolean flag_exit = false;public BroadCast(ServerThread serverThread){this.serverThread = serverThread;}@Overridepublic void run() {boolean flag = true;while(flag_exit){synchronized (serverThread.messages) {if(serverThread.messages.isEmpty()){continue;}else{str = (String)serverThread.messages.firstElement();serverThread.messages.removeElement(str);if(str.contains("@clientThread")){flag = false;}}}synchronized (serverThread.clients) {for(int i=0; i < serverThread.clients.size(); i++){clientThread = serverThread.clients.elementAt(i);if(flag){try{//向纪录的每一个客户端发送数据信息if(str.contains("@exit")){serverThread.clients.remove(i);clientThread.closeClienthread(clientThread);clientThread.dos.writeUTF(str);}if(str.contains("@chat") || str.contains("@userlist") || str.contains("@serverexit")){clientThread.dos.writeUTF(str);}if(str.contains("@single")){String[] info = str.split("@single");int id_thread = Integer.parseInt(info[2]);for(int j = 0; j < serverThread.clients.size(); j++){if(id_thread == serverThread.clients.get(j).getId()){serverThread.clients.get(j).dos.writeUTF(str);i = serverThread.clients.size();break;}}}}catch(IOException E){}}else{String value = ers.get((int)clientThread.getId());if(value.equals("@login@")){flag = true;try{//向纪录的每一个客户端发送数据信息clientThread.dos.writeUTF(str);if(str.contains("@exit")){serverThread.clients.remove(i);clientThread.closeClienthread(clientThread);}}catch(IOException E){}break;}}}}if(str.contains("@serverexit")){ers.clear();flag_exit = false;}}}public void setFlag_exit(boolean b) {flag_exit = b;}public void stopBroadCase() {flag_exit = false;}}package com.server;import java.io.DataInputStream;import java.io.DataOutputStream;import java.io.IOException;import .Socket;import java.text.SimpleDateFormat;import java.util.Date;public class ClientThread extends Thread {public Socket clientSocket;public ServerThread serverThread;public DataInputStream dis;public DataOutputStream dos;public String client_userID;private boolean flag_exit = false;public ClientThread(Socket socket, ServerThread serverThread){。
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客户端以上就是本⽂的全部内容,希望对⼤家的学习有所帮助,也希望⼤家多多⽀持。
- 1、下载文档前请自行甄别文档内容的完整性,平台不提供额外的编辑、内容补充、找答案等附加服务。
- 2、"仅部分预览"的文档,不可在线预览部分如存在完整性等问题,可反馈申请退款(可完整预览的文档不适用该条件!)。
- 3、如文档侵犯您的权益,请联系客服反馈,我们会尽快为您处理(人工客服工作时间:9:00-18:30)。
聊天室客户端主要代码CSocket.hclass CChat_ClientDlg; //dlg类声明class CCSocket : public CSocket{DECLARE_DYNAMIC(CCSocket); //动态类声明public:CCSocket(CChat_ClientDlg* pDlg); //添加构造函数的入口函数virtual ~CCSocket();CChat_ClientDlg* m_pDlg;//指向对话框的指针变量。
virtual void OnReceive(int nErrorCode); //CSocket类添加的事件响应函数};CSokcet.cpp#include"stdafx.h"#include"Chat_Client.h"#include"CSocket.h"#include"Chat_ClientDlg.h" //自行添加的头文件,调用到dlg类的成员函数。
IMPLEMENT_DYNAMIC(CCSocket,CSocket) //动态类声明// CCSocket构造函数、析构函数CCSocket::CCSocket(CChat_ClientDlg* pDlg){m_pDlg=pDlg; //初始化对话框指针变量}CCSocket::~CCSocket(){m_pDlg=NULL;}// CCSocket 成员函数void CCSocket::OnReceive(int nErrorCode){// TODO: 在此添加专用代码和/或调用基类CSocket::OnReceive(nErrorCode);if(nErrorCode==0) m_pDlg->OnReceive(); //调用对话框类的对应函数}CChat_ClientDlg.h#pragma once#include"afxwin.h"#include"Msg.h" //自行添加的包含头文件#include"CSocket.h" //自行添加的包含头文件class CCSocket; //自行添加的类声明// CChat_ClientDlg 对话框类构造函数、析构函数…………protected:HICON m_hIcon;// 生成的消息映射函数virtual BOOL OnInitDialog();afx_msg void OnSysCommand(UINT nID, LPARAM lParam);afx_msg void OnPaint();afx_msg HCURSOR OnQueryDragIcon();afx_msg void OnBnClickedButtonConnect(); //按钮单击事件响应函数声明afx_msg void OnBnClickedButtonClose();afx_msg void OnBnClickedButtonSend();afx_msg void OnDestroy(); //对话框销毁事件响应函数声明DECLARE_MESSAGE_MAP()public:CString m_strSName; // 服务器名称CString m_strCName; // 客户名称//控件变量UINT m_nPort; // 端口号,即聊天室频道CButton m_btnConnect;CButton m_btnClose;CString m_strMsg;CButton m_btnSend;CListBox m_listMsg;CCSocket* m_pSocket; //套接字指针变量CSocketFile* m_pFile;CArchive* m_pArchiveIn; // 用于输入的CArchive对象指针CArchive* m_pArchiveOut; // 用于输出的CArchive对象指针//成员函数void OnReceive(void);void ReceiveMsg(void);void SendMsg(CString strText , bool st);};Chat_ClientDlg.cpp#include"stdafx.h"#include"Chat_Client.h"#include"Chat_ClientDlg.h"#include"Msg.h" //包含头文件#include"CSocket.h" //包含头文件…………//构造函数,初始化变量CChat_ClientDlg::CChat_ClientDlg(CWnd* pParent /*=NULL*/) : CDialog(CChat_ClientDlg::IDD, pParent), m_strSName(_T("")), m_strCName(_T("")), m_nPort(0), m_strMsg(_T("")){m_hIcon = AfxGetApp()->LoadIcon(IDR_MAINFRAME);//初始化自定义变量m_pSocket=NULL;m_pFile=NULL;m_pArchiveIn=NULL;m_pArchiveOut=NULL;}……BEGIN_MESSAGE_MAP(CChat_ClientDlg, CDialog)ON_WM_SYSCOMMAND()ON_WM_PAINT()ON_WM_QUERYDRAGICON()//}}AFX_MSG_MAPON_BN_CLICKED(IDC_BUTTON_CONNECT,&CChat_ClientDlg::OnBnClickedButtonConnect)ON_BN_CLICKED(IDC_BUTTON_CLOSE,&CChat_ClientDlg::OnBnClickedButtonClose)ON_BN_CLICKED(IDC_BUTTON_SEND,&CChat_ClientDlg::OnBnClickedButtonSend)ON_WM_DESTROY()END_MESSAGE_MAP()// CChat_ClientDlg 消息处理程序BOOL CChat_ClientDlg::OnInitDialog(){…………// TODO: 在此添加额外的初始化代码// 初始化文本框变量,更新对话框m_nPort=8000;m_strSName=_T("localhost");UpdateData(FALSE);return TRUE; // 除非将焦点设置到控件,否则返回TRUE }……void CChat_ClientDlg::OnBnClickedButtonConnect(){// TODO: 在此添加控件通知处理程序代码UpdateData(TRUE);m_pSocket=new CCSocket(this); //创建套接字if(!m_pSocket->Create()){delete m_pSocket; // 错误处理m_pSocket=NULL;AfxMessageBox(_T("套接字创建错误!"));return;}if(!m_pSocket->Connect(m_strSName,m_nPort)){delete m_pSocket; // 错误处理m_pSocket=NULL;AfxMessageBox(_T("无法连接服务器!"));return;}m_pFile=new CSocketFile(m_pSocket);m_pArchiveIn=new CArchive(m_pFile,CArchive::load);m_pArchiveOut=new CArchive(m_pFile,CArchive::store);//调用SendMsg函数,向服务器发送消息,表明该客户机进入聊天室CString strTemp;strTemp=m_strCName+_T("进入聊天室"); //发送的消息设为:“客户名”进入聊天室SendMsg(strTemp,FALSE); //m_bClose设为FALSEGetDlgItem(IDC_EDIT_MSG)->EnableWindow(TRUE);GetDlgItem(IDC_BUTTON_CLOSE)->EnableWindow(TRUE);GetDlgItem(IDC_BUTTON_SEND)->EnableWindow(TRUE);GetDlgItem(IDC_EDIT_CLIENTNAME)->EnableWindow(FALSE);GetDlgItem(IDC_BUTTON_CONNECT)->EnableWindow(FALSE);GetDlgItem(IDC_EDIT_SERVNAME)->EnableWindow(FALSE);GetDlgItem(IDC_EDIT_SERVPORT)->EnableWindow(FALSE);}void CChat_ClientDlg::OnBnClickedButtonClose(){// TODO: 在此添加控件通知处理程序代码CString strTemp;strTemp=m_strCName+_T(":离开聊天室!");SendMsg(strTemp,TRUE); //m_bClose设为TRUE//释放资源delete m_pArchiveOut; //删除用于输出的CArchive对象m_pArchiveOut=NULL;delete m_pArchiveIn; //删除用于输入的CArchive对象m_pArchiveIn=NULL;delete m_pFile;m_pFile=NULL;m_pSocket->Close();delete m_pSocket;m_pSocket=NULL;//清空列表框while(m_listMsg.GetCount()!=0)m_listMsg.DeleteString(0);GetDlgItem(IDC_EDIT_MSG)->EnableWindow(FALSE);GetDlgItem(IDC_BUTTON_CLOSE)->EnableWindow(FALSE);GetDlgItem(IDC_BUTTON_SEND)->EnableWindow(FALSE);GetDlgItem(IDC_EDIT_CLIENTNAME)->EnableWindow(TRUE);GetDlgItem(IDC_BUTTON_CONNECT)->EnableWindow(TRUE);GetDlgItem(IDC_EDIT_SERVNAME)->EnableWindow(TRUE);GetDlgItem(IDC_EDIT_SERVPORT)->EnableWindow(TRUE);}void CChat_ClientDlg::OnBnClickedButtonSend(){// TODO: 在此添加控件通知处理程序代码UpdateData(TRUE); //取用户数据if(!m_strMsg.IsEmpty()){this->SendMsg(m_strCName+_T(":")+m_strMsg,FALSE);m_strMsg=_T("");UpdateData(FALSE);}}void CChat_ClientDlg::OnDestroy() //窗口销毁事件响应函数{CDialog::OnDestroy();// TODO: 在此处添加消息处理程序代码if((m_pSocket!=NULL)&&(m_pFile!=NULL)&&(m_pArchiveOut!=NULL)) {//发送客户机离开聊天室的消息CMsg msg;CString strTemp;strTemp=m_strCName+_T("DDDD:离开聊天室!");this->SendMsg(strTemp,TRUE);}delete m_pArchiveOut; //删除用于输出的CArchive对象m_pArchiveOut=NULL;delete m_pArchiveIn; //删除用于输入的CArchive对象m_pArchiveIn=NULL;delete m_pFile;m_pFile=NULL;delete m_pSocket;m_pSocket=NULL;}//CCSocket套接字调用的函数void CChat_ClientDlg::OnReceive(void){do{ReceiveMsg();if(m_pSocket==NULL) return;}while(!m_pArchiveIn->IsBufferEmpty());}//实际接收数据的函数void CChat_ClientDlg::ReceiveMsg(void){CMsg msg;try{//调用消息对象xuliehua函数,接收消息msg.Serialize(*m_pArchiveIn);m_listMsg.AddString(msg.m_strBuf); //将接收到的消息显示在列表框if(msg.m_bClose==true){delete m_pArchiveOut; //删除用于输出的CArchive对象m_pArchiveOut=NULL;delete m_pArchiveIn; //删除用于输入的CArchive对象m_pArchiveIn=NULL;delete m_pFile;m_pFile=NULL;m_pSocket->Close();delete m_pSocket;m_pSocket=NULL;//清空列表框while(m_listMsg.GetCount()!=0)m_listMsg.DeleteString(0);GetDlgItem(IDC_EDIT_MSG)->EnableWindow(FALSE);GetDlgItem(IDC_BUTTON_CLOSE)->EnableWindow(FALSE);GetDlgItem(IDC_BUTTON_SEND)->EnableWindow(FALSE);GetDlgItem(IDC_EDIT_CLIENTNAME)->EnableWindow(TRUE);GetDlgItem(IDC_BUTTON_CONNECT)->EnableWindow(TRUE);GetDlgItem(IDC_EDIT_SERVNAME)->EnableWindow(TRUE);GetDlgItem(IDC_EDIT_SERVPORT)->EnableWindow(TRUE);}}catch(CFileException& e) //错误处理{//显示处理服务器关闭的消息CString strTemp;strTemp=_T("服务器重置连接!连接关闭!");m_listMsg.AddString(strTemp);msg.m_bClose=TRUE;m_pArchiveOut->Abort();//删除相应对象delete m_pArchiveOut; //删除用于输出的CArchive对象m_pArchiveOut=NULL;delete m_pArchiveIn; //删除用于输入的CArchive对象m_pArchiveIn=NULL;delete m_pFile;m_pFile=NULL;m_pSocket->Close();delete m_pSocket;m_pSocket=NULL;}}//实际向服务器发送数据的函数void CChat_ClientDlg::SendMsg(CString strText , bool st) {if(m_pArchiveOut!=NULL){CMsg msg;//将要发送的信息本文赋值给消息对象的成员变量msg.m_strBuf=strText;msg.m_bClose=st;//调用消息对象的序列化函数,发送消息msg.Serialize(*m_pArchiveOut);//将CArchive对象中的数据强制存储到CSocketfile对象中。