C语言用UDP 实现局域网聊天程序源码
见习无聊写的一个基于c# socket udp的简单的局域网聊天软件 含源码

见习无聊写的一个基于c# socket udp的简单的局域网聊天软件含源码实习无聊,写的一个基于c# socket udp的简单的局域网聊天软件含源码最后在公司实习,新人不给活干,就自己随便看看,了解一些DevExpress控件啊,编码规范啊之类的,自己就寻思着写一点点小东西练习练习出于自己对c# socket这块不熟,就选择了这块,顺便可以进一步了解委托代理。
闲话不说,先说下这次做的东西:一个局域网聊天的小软件主要基于udp的通信,如果读者还不知道udp or tcp 那请度娘一下。
直接看图吧:本机端局域网中的另一端猛击我去我的博客查看此软件的详解再猛击我去免费下载源码在软件上设计的不到之处或者源码上编写的问题之处请大家留言发帖指导啊------解决方案--------------------------------------------------------看看...------解决方案--------------------------------------------------------感觉还是不错的、。
美化美化就更好了------解决方案--------------------------------------------------------最后在公司实习,新人不给活干,就自己下载下来看看。
------解决方案--------------------------------------------------------------解决方案--------------------------------------------------------能p2p聊天不,------解决方案--------------------------------------------------------------解决方案--------------------------------------------------------------解决方案--------------------------------------------------------也学习一下吧!------解决方案--------------------------------------------------------来虚心学习------解决方案--------------------------------------------------------好好干,有前途------解决方案--------------------------------------------------------支持一下------解决方案--------------------------------------------------------还真不错! GUI做得挺像那么回事的------解决方案--------------------------------------------------------感觉还不错哦~同是新人,加油哦!------解决方案--------------------------------------------------------学习了。
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客户端以上就是本⽂的全部内容,希望对⼤家的学习有所帮助,也希望⼤家多多⽀持。
用C开发局域网聊天工具

用Socket开发局域网聊天工具(C#)程序设计成为简单的服务端和客户端之间的通信,但通过一些方法可以将这两者进行统一起来,让服务端也成为客户端,让客户端也成为服务端,使它们之间可以互相随时不间断的通信.考虑到实现最原始的服务端和客户端之间的通信所需要的步骤对于写这样的程序是很有帮助的.作为服务端,要声明一个SocketA并绑定(Bind)某一个IP+这个IP指定的通信端口,比如这个是127.0.0.1:9050,然后开始监听(Listen), Listen可以监听来自多个IP传过来的连接请求,具体可以同时连接几个客户端,Listen方法中可以设定一个参数.如果Listen到某一个客户端发来连接请求了,这时定义一个新的SocketB专门负责与这个客户端的通信,SocketB=A.Accept().这时可以获取这个客户端的IP和端口, IPEndPoint C =(IPEndPoint)B.RemoteEndPoint, C.Address和C.Port分别表示客户端C的IP地址和端口.这时通过B.Send()方法就可以给C发送消息了,B.Receive()可以接收客户端C发来的信息.作为客户端,也需要声明一个Socket D并绑定某一个IP+本机一个未被占用的端口,定义IPEndPointE表示要进行连接的服务端Socket,要指明E的IP和端口,这样才可以进行端口对端口之间的通信,接下来就可以尝试D.Connect(E),连接成功之后就可以发送和接收数据了,D.Send(),D.Receive.发送消息时,数据都是以字节或字节数组为单位进行传输的,比如我客户端D要发送"Hello World"则要这样写:D.Send(Encoding.ASCII.GetBytes("Hello World")).接受消息时,也是以字节或字节数组,比如服务端要接受D刚才发送的Hello World,可以这样写:Byte[] data = new Byte[1024]; int receivedDataLength = B.Receive(data);string stringdata = Encoding.ASCII.GetString(data, 0,receivedDataLength); stringdata这时就是Hello World.上面只是大概的阐述了服务端与客户端之间的通信过程,在网上找到了具体的代码例子,也贴过来参考参考.这个例子没有将服务端与客户端统一起来,他是分别写服务端和客户端的.服务端:using System;using System;using ;using .Sockets;using System.Text;namespace tcpserver{/// <summary>/// Class1的摘要说明。
C#使用UDP Client编写聊天程序

★C#使用UDP Client编写聊天程序UDPClient 类使用UDP 与网络服务通讯。
UDP 的优点是简单易用,并且能够同时向多个地址广播消息。
但由于UDP 协议是一个无连接协议,因此发送到远程终结点的UDP 数据文报不一定能够到达,也不一定能够以发送的相同顺序到达。
使用UDP 的应用程序必须准备处理丢失的和顺序有误的数据文报。
若要使用UDP 发送数据文报,必须知道承载所需服务的网络设备的网络地址以及该服务用于通讯的UDP 端口号。
特殊网络地址用于支持基于IP 的网络上的UDP 广播消息。
下面探讨的内容以Internet 上使用的IP 版本4 地址族作为示例。
IP 版本4 地址使用32 位指定网络地址。
对于使用255.255.255.0 网络掩码的C 类地址,这些位被分为四个八位字节。
当以十进制数表示时,这四个八位字节构成熟悉的以点分隔的四部分表示法,如192.168.100.2。
前两个八位字节(此示例中为192.168)构成网络号;第三个八位字节(100) 定义子网;最后一个八位字节(2) 是主机标识符。
将IP 地址的所有位均设置为1(即255.255.255.255)可构成有限的广播地址。
将UDP 数据文报发送到此地址可将消息传递到该广播网络上的任何主机。
由于路由器从不转发发送到此地址的消息,因此只有已连接的网络上的主机才可看到这些广播。
通过将部分地址的所有位全都设置为1,可以将广播定向到特定的网络部分。
例如,若要将广播发送到以192.168 打头的IP 地址标识的网络上的所有主机,请将地址的子网和主机部分全都设置为1,如192.168.255.255。
若要将广播限制在单个子网,则只将主机部分设置全都为1,如192.168.100.255。
UdpClient 类可向任何网络广播地址广播,但它无法侦听发送到网络的广播。
必须使用Socket 类才能侦听网络广播。
当所有接收者都位于单个网络中时,或者当许多客户端需要接收广播时,广播地址将起作用。
计算机毕业设计85UDP局域网QQ聊天程序设计说明书

摘要随着网络技术的发展及人们生活的需求,网络聊天已越来越受到人们的青睐。
网络聊天已经成为人们工作生活中传递信息、交流感情的重要工具,给人们带来了很大的方便。
本设计开发的是一个局域网QQ聊天软件,运用软件工程的设计流程,使用现在比较普遍和流行的C#语言,采用面向对象的方法,综合运用数据库编程技术、多线程开发技术、网络通讯技术,以Microsoft Visual Studio 2005作为系统前台应用程序开发工具,Microsoft SQL Server 2000作为后台数据库管理系统,在Windows XP平台下进行开发。
本局域网QQ聊天软件采用服务器端/客户端(C/S)模式。
客户端采用UDP与服务器连接,客户端之间也是通过UDP互相通讯。
服务器端主要用于开启和关闭UDP协议的监听服务,还可以查看局域网内已注册的所有的用户以及他们的在线状态。
客户端分为注册窗口、登录窗口、QQ窗体主界面以及聊天界面。
服务器端要先开启监听服务,客户端才可以进行登录,然后才可以与其他登录的在线用户进行文本信息的聊天,还可以进行点对点的语音聊天,视频聊天和文件传输,还可以进行拍照和录像等。
此外,还对该软件进行了皮肤的加载以及打包成安装源。
该软件运行稳定,界面美观、操作简便。
在局域网内部使用该局域网QQ聊天软件,可以方便人与人之间的沟通、交流;可以大大提高企业的工作效率;拉近人与人之间的关系。
关键词:局域网;聊天软件;客户端;服务器端;UDP协议AbstractWith the development of networking technology and the living demand of people, chatting on network is more and more acceptable by people. Internet chat has become an important tool to transmission of information and exchange of feelings in our life, it brings a great convenience.The topic of this paper is going to talk about that to develop the local area network QQ chat software. This local area network chat software using the design stream of the software project, using the C# language which is very common and popular, using the object-oriented approach, the technology of the database programming, multi-threading development technology and the network communication technology, makes Microsoft Visual Studio 2005 as the front application design tool, Microsoft SQL Server 2000 are used as the background DBMS( the database management system ), and it was programmed in the Windows XP System.The local area network QQ chat software uses the server and client (C/S) mechanism. And the client connects the server using UDP, and they communicate each other by UDP. Server-side is mainly used to open and close the UDP protocol monitoring service, and you can also look over all the registered users and their online status whom in the local area network. Client is divided into registration window, the login window, the main QQ form and the chat form. If the client wants to log in, the server monitoring service must first open the listening service, then the client can chat with the others which have already logged, and also can voice chat, video chat and files transfers, and also can take pictures and videos. In addition, the software has been load the beautiful skin and package into the installation source.This software has an interface aesthetics, stable operation, simple operation. Using QQ software in the LAN internal can help people to communicate with others easily, can greatly improve the efficiency of the enterprises, close relationships between people.Key Words: Local Area Network; Chat Software; Client; Server-side; UDP protocol目录引言 (1)1系统概述与需求分析 (2)1.1 系统概述 (2)1.2 需求分析 (2)1.2.1功能需求 (3)1.2.2性能需求 (3)1.3 可行性分析 (4)2 系统总体设计 (5)2.1 相关开发技术的原理性说明 (5) Framework和C# (5)2.1.2SQL Server 2005 (6)2.1.3UDP协议简介 (6)2.1.4Socket简介 (6)2.2 系统功能结构 (7)2.3 业务流程图 (8)2.4 程序运行环境 (8)3 数据库以及类库的详细设计与实现 (9)3.1 数据库的创建 (9)3.1.1数据库分析 (9)3.1.2数据库创建 (9)3.1.3数据库概念设计 (9)3.1.4数据库逻辑结构设计 (9)3.1.5文件夹组织结构 (10)3.2 类库的设计 (10)4 客户端模块的详细设计及实现 (12)4.1客户端注册模块的设计 (12)4.1.1客户端注册模块概述 (12)4.1.2客户端注册模块技术分析 (13)4.1.3客户端注册模块实现过程 (13)4.2 客户端登陆模块设计 (14)4.2.1客户端登陆模块概述 (14)4.2.2客户端登陆模块技术分析 (14)4.2.3客户端登陆模块实现过程 (14)4.3 客户端QQ模块设计 (15)4.3.1客户端QQ模块概述 (15)4.3.2客户端QQ模块技术分析 (15)4.3.3客户端QQ模块实现过程 (16)4.4 客户端消息发送模块设计 (17)4.4.1客户端消息发送模块概述 (17)4.4.2客户端消息发送模块技术分析 (18)4.4.3客户端消息发送模块实现过程 (18)5 服务器端模块的详细设计与实现 (23)5.1 服务器端控制台窗体概述 (23)5.2 服务器端控制台窗体技术分析 (23)5.3 服务器端控制台窗体实现过程 (23)6 系统特色及关键技术 (24)7 结论 (25)谢辞 (28)参考文献 (29)附录 (30)引言在Internet飞速发展的今天,互联网成为人们快速获取、发布和传递信息的重要渠道,它在人们政治、经济、生活等各个方面发挥着重要的作用。
局域网聊天软件源代码包括语音聊天

局域网聊天软件源代码包括语音聊天// Chat.h : PROJECT_NAME 应用程序的主头文件//#pragma once#ifndef __AFXWIN_H__#error "在包含此文件之前包含“stdafx.h”以生成PCH 文件" #endif#include "resource.h" // 主符号// CChatApp:// 有关此类的实现,请参阅Chat.cpp//class CChatApp : public CWinApp{public:CChatApp();// 重写public:virtual BOOL InitInstance();// 实现DECLARE_MESSAGE_MAP()};extern CChatApp theApp;// Chat.cpp : 定义应用程序的类行为。
//#include "stdafx.h"#include "Chat.h"#include "ChatDlg.h"//#ifdef _DEBUG//#define new DEBUG_NEW// CChatAppBEGIN_MESSAGE_MAP(CChatApp, CWinApp)ON_COMMAND(ID_HELP, &CWinApp::OnHelp)END_MESSAGE_MAP()// CChatApp 构造CChatApp::CChatApp(){// TODO: 在此处添加构造代码,// 将所有重要的初始化放置在InitInstance 中}// 唯一的一个CChatApp 对象CChatApp theApp;// CChatApp 初始化BOOL CChatApp::InitInstance(){// 如果一个运行在Windows XP 上的应用程序清单指定要// 使用ComCtl32.dll 版本6 或更高版本来启用可视化方式,//则需要InitCommonControlsEx()。
(精品)UDP局域网聊天室实现

} msg_t;
分析函数实现:
服务器端:
1.int send_assign_client(int serfd,Linklist *head,msg_t *pmsg); 功能:
通过名字查找对应的客户端是否存在,存在则发送消息 不存在返回出错信息表示客户端不存在
那么我们分析一下该链表的数据结构构建。 数据结构 地址信息节点:
typedef struct node { struct sockaddr_in addr; struct node *next;
} data_t;
//消息类型
#define CLIENT_TALK 100 #define SERVER_TALK 200
分析客户端的流程:
客户端: 整体的流程首先是 网络的基本编程
socket pid = fork(); if (pid > 0) //父进程,主要功能,数据发送 {
while (1) { //大循环 1.发送一个登录的消息,告诉大家我上线了 2..从键盘获得数据 a.聊天的对端的名字 SYSTERM 群聊消息 非SYSTERM 私聊消息 c.聊天的内容 d.输入quit时,结束 3.聊天结束,发送一个聊天结束的消息给大家,告诉大家说我下线了
/* See NOTES */
} } } else if (pid == 0)//子进程,主要功能,数据接收 {
while (1) { 1.接收数据 2.显示数据
}
}
分析"服务器端"的流程:
整体的流程是 UDP的网络服务器的 基本编程
socket bind pid = fork(); if (pid >0)//父进程 发数据,系统级别的消息,给所有客户端发送消息 {
VC++之网络编程五聊天编程实例(UDP)

VC++之⽹络编程五聊天编程实例(UDP)Server:#include <Winsock2.h>#include <stdio.h>void main(){//mide delete wordWORD wVersionRequested;WSADATA wsaData;int err;wVersionRequested=MAKEWORD(2,2);err=WSAStartup(wVersionRequested,&wsaData);if(err!=0){return;}if(LOBYTE(wsaData.wVersion)!=2 || HIBYTE(wsaData.wHighVersion)!=2){WSACleanup();return ;}SOCKET sockSrv=socket(AF_INET,SOCK_DGRAM,0);SOCKADDR_IN addrSrv;addrSrv.sin_addr.S_un.S_addr=htonl(INADDR_ANY);addrSrv.sin_family=AF_INET;addrSrv.sin_port=htons(6000);bind(sockSrv,(SOCKADDR*)&addrSrv,sizeof(SOCKADDR));char recvBuf[100];char sendBuf[100];char tempBuf[100];SOCKADDR_IN addrClient;int len=sizeof(SOCKADDR);while(1){recvfrom(sockSrv,recvBuf,100,0,(SOCKADDR*)&addrClient,&len);if('q'==recvBuf[0]){sendto(sockSrv,"q",strlen("q")+1,0,(SOCKADDR*)&addrClient,len);printf("chat end!/n");break;}sprintf(tempBuf,"%s say: %s",inet_ntoa(addrClient.sin_addr),recvBuf);printf("%s/n",tempBuf);printf("Please input data:/n");gets(sendBuf);sendto(sockSrv,sendBuf,strlen(sendBuf)+1,0,(SOCKADDR*)&addrClient,len);}closesocket(sockSrv);WSACleanup();}client:#include <Winsock2.h>#include <stdio.h>void main(){//mide delete wordWORD wVersionRequested;WSADATA wsaData;int err;wVersionRequested=MAKEWORD(2,2);err=WSAStartup(wVersionRequested,&wsaData);if(err!=0){return;}if(LOBYTE(wsaData.wVersion)!=2 || HIBYTE(wsaData.wHighVersion)!=2){WSACleanup();return ;}SOCKET sockClient=socket(AF_INET,SOCK_DGRAM,0);SOCKADDR_IN addrSrv;addrSrv.sin_addr.S_un.S_addr=inet_addr("127.0.0.1");addrSrv.sin_family=AF_INET;addrSrv.sin_port=htons(6000);sendto(sockClient,"Hello",strlen("Hello")+1,0,(SOCKADDR*)&addrSrv,sizeof(SOCKADDR));closesocket(sockClient);WSACleanup();}注意:server 和 client 都要"项⽬属性"--->"配置属性"----> "链接"----> "输⼊" --->"附加依赖项"中添加"ws2_32.lib"。
- 1、下载文档前请自行甄别文档内容的完整性,平台不提供额外的编辑、内容补充、找答案等附加服务。
- 2、"仅部分预览"的文档,不可在线预览部分如存在完整性等问题,可反馈申请退款(可完整预览的文档不适用该条件!)。
- 3、如文档侵犯您的权益,请联系客服反馈,我们会尽快为您处理(人工客服工作时间:9:00-18:30)。
#include <stdio.h>#include <stdlib.h>#include <string.h>#include <sys/types.h>#include <sys/socket.h>#include <arpa/inet.h>#include <unistd.h>#include <signal.h>#define CLIENT_LOGIN 100#define CLIENT_CHAT 200#define CLIENT_QUIT 300#define SERVER_CHA T 400#define SERVER_QUIT 500struct node{char name[20];struct sockaddr_in client_addr;struct node *next;};struct message{long type;char name[20];char mtext[512];};struct node *create_list(void);void insert_list(struct node *, char *, struct sockaddr_in *);void delete_list(struct node *, char *);void recv_message(int , struct node *);void send_message(int , struct sockaddr_in *, pid_t );void client_login(int , struct node *, struct message *, struct sockaddr_in *); void client_chat(int , struct node *, struct message *);void client_quit(int , struct node *, struct message *);void server_chat(int , struct node *, struct message *);void server_quit(int , struct node *, struct message *);void brocast_msg(int , struct node *, struct message *);void father_func(int sig_no){return ;}int main(int argc, const char *argv[]){int socket_fd;pid_t pid;struct sockaddr_in server_addr;struct node *head;if (argc < 3){fprintf(stderr, "usages : %s ip port\n", argv[0]);exit(-1);}if ((socket_fd = socket(AF_INET, SOCK_DGRAM, 0)) < 0){perror("failed to create socket");exit(-1);}head = create_list();server_addr.sin_family = AF_INET;server_addr.sin_port = htons(atoi(argv[2]));server_addr.sin_addr.s_addr = inet_addr(argv[1]);if (bind(socket_fd, (struct sockaddr *)&server_addr, sizeof(server_addr)) < 0) {perror("failed to bind");exit(-1);}if ((pid = fork()) < 0) //创建子经常{perror("failed to fork pid");exit(-1);}if (pid == 0)recv_message(socket_fd, head);elsesend_message(socket_fd, &server_addr, pid);return 0;}struct node *create_list(void){struct node *head;head = (struct node *)malloc(sizeof(struct node));head->next = NULL;return head;}void insert_list(struct node *head, char *name, struct sockaddr_in *client_addr) {struct node *new;new = (struct node *)malloc(sizeof(struct node));strcpy(new->name, name);new->client_addr = *client_addr;new->next = head->next;head->next = new;return ;}void delete_list(struct node *head, char *name){struct node *p = head->next;struct node *q = head;while (p != NULL){if (strcmp(p->name, name) == 0)break;p = p->next;q = q->next;}q->next = p->next;p->next = NULL;free(p);return ;}void recv_message(int socket_fd, struct node *head){struct message msg;struct sockaddr_in client_addr;int client_addrlen = sizeof(struct sockaddr);while (1){if (recvfrom(socket_fd, &msg, sizeof(msg), 0, (struct sockaddr *)&client_addr, &client_addrlen) < 0){perror("failed to recvform client");exit(-1);}switch(msg.type){case CLIENT_LOGIN:client_login(socket_fd, head, &msg, &client_addr);break;case CLIENT_CHA T:client_chat(socket_fd, head, &msg);break;case CLIENT_QUIT:client_quit(socket_fd, head, &msg);break;case SERVER_CHA T:server_chat(socket_fd, head, &msg);break;case SERVER_QUIT:server_quit(socket_fd, head, &msg);break;default:break;}}return ;}void send_message(int socket_fd, struct sockaddr_in *server_addr, pid_t pid){struct message msg;char buf[512];signal(getppid(), father_func);while (1){usleep(500);printf(">");fgets(buf, sizeof(buf), stdin);buf[strlen(buf) - 1] = 0;strcpy(msg.mtext, buf);strcpy( , "server");msg.type = SERVER_CHA T;if (strncmp(buf, "quit", 4) == 0){msg.type = SERVER_QUIT;if (sendto(socket_fd, &msg, sizeof(msg), 0,(struct sockaddr *)server_addr, sizeof(struct sockaddr)) < 0) {perror("failed to send server_quit message");exit(-1);}pause();kill(pid, SIGKILL);waitpid(pid, NULL, 0);exit(0);}if (sendto(socket_fd, &msg, sizeof(msg), 0, (struct sockaddr *)server_addr, sizeof(struct sockaddr)) < 0){perror("failed to send server_chat message");exit(-1);}}return ;}void client_login(int socket_fd, struct node *head, struct message *msg, struct sockaddr_in *client_addr){printf("********Login In********\n");printf("%s is Login In\n", msg->name);printf("************************\n");insert_list(head, msg->name, client_addr);brocast_msg(socket_fd, head, msg);return ;}void client_chat(int socket_fd, struct node *head, struct message *msg){printf("********Group Chat********\n");printf("name: %s\n", msg->name);printf("msg: %s\n", msg->mtext);printf("**************************\n");brocast_msg(socket_fd, head, msg);return ;}void client_quit(int socket_fd, struct node *head, struct message *msg){printf("*********Quit Msg********\n");printf("%s is Quit\n", msg->name);printf("*************************\n");delete_list(head, msg->name);brocast_msg(socket_fd, head, msg);return ;}void server_chat(int socket_fd, struct node *head, struct message *msg){printf("********Server Msg*********\n");printf("msg: %s\n", msg->mtext);printf("***************************\n");brocast_msg(socket_fd, head, msg);return ;}void server_quit(int socket_fd, struct node *head, struct message *msg){brocast_msg(socket_fd, head, msg);kill(getppid(), SIGUSR1);return ;}void brocast_msg(int socket_fd, struct node *head, struct message *msg){struct node *p = head->next;while(p != NULL){if (msg->type == CLIENT_LOGIN){if (strcmp(p->name, msg->name) == 0){p = p->next;continue;}}sendto(socket_fd, msg, sizeof(struct message), 0, (struct sockaddr *)&(p->client_addr), sizeof(struct sockaddr));p = p->next;}return ; }#include <stdio.h>#include <stdlib.h>#include <string.h>#include <sys/types.h>#include <sys/socket.h>#include <arpa/inet.h>#include <unistd.h>#include <signal.h>#define CLIENT_LOGIN 100#define CLIENT_CHAT 200#define CLIENT_QUIT 300#define SERVER_CHA T 400#define SERVER_QUIT 500struct message{long type;char name[20];char mtext[512];};void recv_message(int );void send_message(int , struct sockaddr_in *, char *, pid_t);void login_msg(struct message *);void group_msg(struct message *);void quit_msg(struct message *);void server_msg(struct message *);void server_quit(void);int main(int argc, char *argv[]){pid_t pid;int server_fd;struct sockaddr_in server_addr;if (argc < 4){fprintf(stderr, "usages: %s ip port name\n", argv[0]);exit(-1);}if ((server_fd = socket(AF_INET, SOCK_DGRAM, 0)) < 0){perror("failed to create server_fd");exit(-1);}server_addr.sin_family = AF_INET;server_addr.sin_port = htons(atoi(argv[2]));server_addr.sin_addr.s_addr = inet_addr(argv[1]);if ((pid = fork()) < 0){perror("failed to fork pid");exit(-1);}if (pid == 0)recv_message(server_fd);elsesend_message(server_fd, &server_addr, argv[3], pid);return 0;}void recv_message(int server_fd){struct message msg;while (1){memset(&msg, 0, sizeof(msg));if (recvfrom(server_fd, &msg, sizeof(msg), 0, NULL, NULL) < 0){perror("failed to recv server message");exit(-1);}switch(msg.type){case CLIENT_LOGIN:login_msg(&msg);break;case CLIENT_CHA T:group_msg(&msg);break;case CLIENT_QUIT:quit_msg(&msg);break;case SERVER_CHA T:server_msg(&msg);break;case SERVER_QUIT:server_quit();break;default:break;}}return ;}void send_message(int server_fd, struct sockaddr_in *server_addr, char *name, pid_t pid) {struct message msg;char buf[512];msg.type = CLIENT_LOGIN;strcpy(, name);if (sendto(server_fd, &msg, sizeof(msg), 0,(struct sockaddr *)server_addr, sizeof(struct sockaddr)) < 0) {perror("failed to send login message");exit(-1);}while(1){memset(buf, 0, sizeof(buf));memset(&msg, 0, sizeof(msg));usleep(500);printf(">");fgets(buf, sizeof(buf), stdin);buf[strlen(buf) - 1] = 0;strcpy(msg.mtext, buf);strcpy(, name);msg.type = CLIENT_CHAT;if (strncmp(buf, "quit", 4) == 0){msg.type = CLIENT_QUIT;if (sendto(server_fd, &msg, sizeof(msg), 0,(struct sockaddr *)server_addr, sizeof(struct sockaddr)) < 0) {perror("failed to send quit message");exit(-1);}kill(pid, SIGKILL);waitpid(pid, NULL, 0);exit(0);}if (sendto(server_fd, &msg, sizeof(msg), 0,(struct sockaddr *)server_addr, sizeof(struct sockaddr)) < 0) {perror("failed to send group message");exit(-1);}}return ;}void login_msg(struct message *msg)printf("######## Login in ########\n");printf("%s is login in\n", msg->name);printf("######## Login in ########\n");return ;}void group_msg(struct message *msg){printf("******** Group Msg ********\n");printf("name: %s\n", msg->name);printf("msg: %s\n", msg->mtext);printf("******** Group Msg ********\n");return ;}void quit_msg(struct message *msg){printf("######## Quit Msg ########\n");printf("%s is Quit\n", msg->name);printf("######## Quit Msg ########\n");return ;}void server_msg(struct message *msg){printf("******** Server Msg ********\n");printf("msg: %s\n", msg->mtext);printf("******** Server Msg ********\n");return ;}void server_quit(void ){kill(getppid(), SIGKILL);exit(0);}。