socket多人聊天程序C语言版

socket多人聊天程序C语言版
socket多人聊天程序C语言版

socket多人聊天程序C语言版

1V1实现了,1V多也就容易了。不过相对于1V1的程序,我经过大改,采用链表来动态管理。这样效率真的提升不少,至少CPU使用率稳稳的在20以下,不会飙到100了。用C语言写这个还是挺费时间的,因为什么功能函数都要自己写,不像C++有STL库可以用,MFC 写就更简单了,接下来我还会更新MFC版本的多人聊天程序。好了,废话少说,进入主题。

这个程序要解决的问题如下:

1.CPU使用率飙升问题–>用链表动态管理

2.用户自定义聊天,就是想跟谁聊跟谁聊–> _Client结构体中新增一个ChatName字段,用来表示要和谁聊天,这个字段很重要,因为server转发消息的时候就是按照这个字段来转发的。

3.中途换人聊天,就是聊着聊着,想和别人聊,而且自己还一样能接收到其它人发的消息–> 这个就要小改客户端的代码了,可以在发送聊天消息之前插入一段代码,用来切换聊天用户。具体做法就是,用getch()函数读取ESC键,如果用户按了这个键,则表示想切换用户,然后会输出一行提示,请输入chat name,就是想要和谁聊天的名字,发送这个名字过去之前要加一个标识符,表示这个消息是切换聊天用户消息。然后server接收到这个消息后会判断第一个字符是不是标识符,第二个字符不能是标识符,则根据这个name来查找当前在线的用户,然后修改想切换聊天用户的ChatName为name这个用户。(可能有点绕,不懂的看代码就清晰易懂了~)

4.下线后提醒对方–> 还是老套路,只要send对方不通就当对方下线了。

编写环境:WIN10,VS2015

效果图:

为了方便就不用虚拟机演示了,但是在虚拟机是肯定可以的,应该说只要是局域网,能互相ping通就可以使用这个程序。

Server code:

链表头文件:

#ifndef _CLIENT_LINK_LIST_H_

#define _CLIENT_LINK_LIST_H_

#include

#include

//客户端信息结构体

typedef struct _Client

{

SOCKET sClient; //客户端套接字

char buf[128]; //数据缓冲区

char userName[16]; //客户端用户名

char IP[20]; //客户端IP

unsigned short Port; //客户端端口

UINT_PTR flag; //标记客户端,用来区分不同的客户端

char ChatName[16]; //指定要和哪个客户端聊天

_Client* next; //指向下一个结点

}Client, *pClient;

/*

* function 初始化链表

* return 无返回值

*/

void Init();

/*

* function 获取头节点

* return 返回头节点

*/

pClient GetHeadNode();

/*

* function 添加一个客户端

* param client表示一个客户端对象

* return 无返回值

*/

void AddClient(pClient client);

/*

* function 删除一个客户端

* param flag标识一个客户端对象

* return 返回true表示删除成功,false表示失败

*/

bool RemoveClient(UINT_PTR flag);

/*

* function 根据name查找指定客户端

* param name是指定客户端的用户名

* return 返回一个client表示查找成功,返回INVALID_SOCKET表示无此用户*/

SOCKET FindClient(char* name);

/*

* function 根据SOCKET查找指定客户端

* param client是指定客户端的套接字

* return 返回一个pClient表示查找成功,返回NULL表示无此用户

*/

pClient FindClient(SOCKET client);

/*

* function 计算客户端连接数

* param client表示一个客户端对象

* return 返回连接数

*/

int CountCon();

/*

* function 清空链表

* return 无返回值

*/

void ClearClient();

/*

* function 检查连接状态并关闭一个连接

* return 返回值

*/

void CheckConnection();

/*

* function 指定发送给哪个客户端

* param FromName,发信人

* param ToName, 收信人

* param data, 发送的消息

*/

void SendData(char* FromName, char* ToName, char* data);

#endif //_CLIENT_LINK_LIST_H_

链表cpp文件:

?

#include "ClientLinkList.h"

pClient head = (pClient)malloc(sizeof(_Client)); //创建一个头结点

/*

* function 初始化链表

* return 无返回值

*/

{

head->next = NULL;

}

/*

* function 获取头节点

* return 返回头节点

*/

pClient GetHeadNode()

{

return head;

}

/*

* function 添加一个客户端

* param client表示一个客户端对象

* return 无返回值

*/

void AddClient(pClient client)

{

client->next = head->next; //比如:head->1->2,然后添加一个3进来后是head->next = client; //3->1->2,head->3->1->2

}

/*

* function 删除一个客户端

* param flag标识一个客户端对象

* return 返回true表示删除成功,false表示失败

*/

bool RemoveClient(UINT_PTR flag)

{

//从头遍历,一个个比较

pClient pCur = head->next;//pCur指向第一个结点

pClient pPre = head; //pPre指向head

while (pCur)

{

// head->1->2->3->4,要删除2,则直接让1->3

if (pCur->flag == flag)

{

pPre->next = pCur->next;

closesocket(pCur->sClient); //关闭套接字

free(pCur); //释放该结点

return true;

pPre = pCur;

pCur = pCur->next;

}

return false;

}

/*

* function 查找指定客户端

* param name是指定客户端的用户名

* return 返回socket表示查找成功,返回INVALID_SOCKET表示无此用户*/

SOCKET FindClient(char* name)

{

//从头遍历,一个个比较

pClient pCur = head;

while (pCur = pCur->next)

{

if (strcmp(pCur->userName, name) == 0)

return pCur->sClient;

}

return INVALID_SOCKET;

}

/*

* function 根据SOCKET查找指定客户端

* param client是指定客户端的套接字

* return 返回一个pClient表示查找成功,返回NULL表示无此用户

*/

pClient FindClient(SOCKET client)

{

//从头遍历,一个个比较

pClient pCur = head;

while (pCur = pCur->next)

{

if (pCur->sClient == client)

return pCur;

}

return NULL;

}

/*

* function 计算客户端连接数

* param client表示一个客户端对象

* return 返回连接数

*/

int CountCon()

{

int iCount = 0;

pClient pCur = head;

while (pCur = pCur->next)

iCount++;

return iCount;

}

/*

* function 清空链表

* return 无返回值

*/

void ClearClient()

{

pClient pCur = head->next;

pClient pPre = head;

while (pCur)

{

//head->1->2->3->4,先删除1,head->2,然后free 1

pClient p = pCur;

pPre->next = p->next;

free(p);

pCur = pPre->next;

}

}

/*

* function 检查连接状态并关闭一个连接

* return 返回值

*/

void CheckConnection()

{

pClient pclient = GetHeadNode();

while (pclient = pclient->next)

{

if (send(pclient->sClient, "", sizeof(""), 0) == SOCKET_ERROR)

{

if (pclient->sClient != 0)

{

printf("Disconnect from IP: %s,UserName: %s\n", pclient->IP, pclient->userName);

char error[128] = { 0 }; //发送下线消息给发消息的人

sprintf(error, "The %s was downline.\n", pclient->userName);

send(FindClient(pclient->ChatName), error, sizeof(error), 0);

closesocket(pclient->sClient); //这里简单的判断:若发送消息失败,则认为连接中断(其原因有多种),关闭该套接字

RemoveClient(pclient->flag);

break;

}

}

}

}

/*

* function 指定发送给哪个客户端

* param FromName,发信人

* param ToName, 收信人

* param data, 发送的消息

*/

void SendData(char* FromName, char* ToName, char* data)

{

SOCKET client = FindClient(ToName); //查找是否有此用户

char error[128] = { 0 };

int ret = 0;

if (client != INVALID_SOCKET && strlen(data) != 0)

{

char buf[128] = { 0 };

sprintf(buf, "%s: %s", FromName, data); //添加发送消息的用户名

ret = send(client, buf, sizeof(buf), 0);

}

else//发送错误消息给发消息的人

{

if(client == INVALID_SOCKET)

sprintf(error, "The %s was downline.\n", ToName);

else

sprintf(error, "Send to %s message not allow empty, Please try again!\n", ToName);

send(FindClient(FromName), error, sizeof(error), 0);

}

if (ret == SOCKET_ERROR)//发送下线消息给发消息的人

{

sprintf(error, "The %s was downline.\n", ToName);

send(FindClient(FromName), error, sizeof(error), 0);

}

}

server cpp:

?

/*

#include

#include

#include

#include "ClientLinkList.h"

#pragma comment(lib,"ws2_32.lib")

SOCKET g_ServerSocket = INVALID_SOCKET; //服务端套接字SOCKADDR_IN g_ClientAddr = { 0 }; //客户端地址

int g_iClientAddrLen = sizeof(g_ClientAddr);

typedef struct _Send

{

char FromName[16];

char ToName[16];

char data[128];

}Send,*pSend;

//发送数据线程

unsigned __stdcall ThreadSend(void* param)

{

pSend psend = (pSend)param; //转换为Send类型

SendData(psend->FromName, psend->ToName, psend->data); //发送数据return 0;

}

//接受数据

unsigned __stdcall ThreadRecv(void* param)

{

int ret = 0;

while (1)

{

pClient pclient = (pClient)param;

if (!pclient)

return 1;

ret = recv(pclient->sClient, pclient->buf, sizeof(pclient->buf), 0);

if (ret == SOCKET_ERROR)

return 1;

if (pclient->buf[0] == '#' && pclient->buf[1] != '#') //#表示用户要指定另一个用户进行聊天

{

SOCKET socket = FindClient(&pclient->buf[1]); //验证一下客户是否存在

if (socket != INVALID_SOCKET)

{

pClient c = (pClient)malloc(sizeof(_Client));

c = FindClient(socket); //只要改变ChatName,发送消息的时候就会自动发给指定的用户了

memset(pclient->ChatName, 0, sizeof(pclient->ChatName));

memcpy(pclient->ChatName , c->userName,sizeof(pclient->ChatName));

}

else

send(pclient->sClient, "The user have not online or not exits.",64,0);

continue;

}

pSend psend = (pSend)malloc(sizeof(_Send));

//把发送人的用户名和接收消息的用户和消息赋值给结构体,然后当作参数传进发送消息进程中

memcpy(psend->FromName, pclient->userName, sizeof(psend->FromName));

memcpy(psend->ToName, pclient->ChatName, sizeof(psend->ToName));

memcpy(psend->data, https://www.360docs.net/doc/526977022.html,->buf, sizeof(psend->data));

_beginthreadex(NULL, 0, ThreadSend, psend, 0, NULL);

Sleep(200);

}

return 0;

}

//开启接收消息线程

void StartRecv()

{

pClient pclient = GetHeadNode();

while (pclient = pclient->next)

_beginthreadex(NULL, 0, ThreadRecv, pclient, 0, NULL);

}

//管理连接

unsigned __stdcall ThreadManager(void* param)

{

while (1)

{

CheckConnection(); //检查连接状况

Sleep(2000); //2s检查一次

}

return 0;

}

//接受请求

unsigned __stdcall ThreadAccept(void* param)

{

_beginthreadex(NULL, 0, ThreadManager, NULL, 0, NULL);

Init(); //初始化一定不要再while里面做,否则head会一直为NULL!!!

while (1)

{

//创建一个新的客户端对象

pClient pclient = (pClient)malloc(sizeof(_Client));

//如果有客户端申请连接就接受连接

if ((pclient->sClient = accept(g_ServerSocket, (SOCKADDR*)&g_ClientAddr, &g_iClientAddrLen)) == INVALID_SOCKET)

{

printf("accept failed with error code: %d\n", WSAGetLastError());

closesocket(g_ServerSocket);

WSACleanup();

return -1;

}

recv(pclient->sClient, pclient->userName, sizeof(pclient->userName), 0); //接收用户名和指定聊天对象的用户名

recv(pclient->sClient, pclient->ChatName, sizeof(pclient->ChatName), 0);

memcpy(pclient->IP, inet_ntoa(g_ClientAddr.sin_addr), sizeof(pclient->IP)); //记录客户端IP

pclient->flag = pclient->sClient; //不同的socke有不同UINT_PTR类型的数字来标识

pclient->Port = htons(g_ClientAddr.sin_port);

AddClient(pclient); //把新的客户端加入链表中

printf("Successfuuly got a connection from IP:%s ,Port: %d,UerName: %s , ChatName: %s\n",

pclient->IP, pclient->Port, pclient->userName,pclient->ChatName);

if (CountCon() >= 2) //当至少两个用户都连接上服务器后才

进行消息转发

StartRecv();

Sleep(2000);

}

return 0;

}

//启动服务器

int StartServer()

{

//存放套接字信息的结构

WSADATA wsaData = { 0 };

SOCKADDR_IN ServerAddr = { 0 }; //服务端地址

USHORT uPort = 18000; //服务器监听端口

//初始化套接字

if (WSAStartup(MAKEWORD(2, 2), &wsaData))

{

printf("WSAStartup failed with error code: %d\n", WSAGetLastError());

return -1;

}

//判断版本

if (LOBYTE(wsaData.wVersion) != 2 || HIBYTE(wsaData.wVersion) != 2)

{

printf("wVersion was not 2.2\n");

return -1;

}

//创建套接字

g_ServerSocket = socket(AF_INET, SOCK_STREAM, IPPROTO_TCP);

if (g_ServerSocket == INVALID_SOCKET)

{

printf("socket failed with error code: %d\n", WSAGetLastError());

return -1;

}

//设置服务器地址

ServerAddr.sin_family = AF_INET;//连接方式

ServerAddr.sin_port = htons(uPort);//服务器监听端口

ServerAddr.sin_addr.S_un.S_addr = htonl(INADDR_ANY);//任何客户端都能连接这个服务器

//绑定服务器

if (SOCKET_ERROR == bind(g_ServerSocket, (SOCKADDR*)&ServerAddr, sizeof(ServerAddr)))

{

printf("bind failed with error code: %d\n", WSAGetLastError());

closesocket(g_ServerSocket);

return -1;

}

//设置监听客户端连接数

if (SOCKET_ERROR == listen(g_ServerSocket, 20000))

{

printf("listen failed with error code: %d\n", WSAGetLastError());

closesocket(g_ServerSocket);

WSACleanup();

return -1;

}

_beginthreadex(NULL, 0, ThreadAccept, NULL, 0, 0);

for (int k = 0;k < 100;k++) //让主线程休眠,不让它关闭TCP连接.

Sleep(10000000);

//关闭套接字

ClearClient();

closesocket(g_ServerSocket);

WSACleanup();

return 0;

}

int main()

{

StartServer(); //启动服务器

return 0;

}

Client code:

?

#define _WINSOCK_DEPRECATED_NO_WARNINGS

#include

#include

#include

#include

#include

#pragma comment(lib,"ws2_32.lib")

#define RECV_OVER 1

#define RECV_YET 0

char userName[16] = { 0 };

char chatName[16] = { 0 };

int iStatus = RECV_YET;

//接受数据

unsigned __stdcall ThreadRecv(void* param)

{

char buf[128] = { 0 };

while (1)

{

int ret = recv(*(SOCKET*)param, buf, sizeof(buf), 0);

if (ret == SOCKET_ERROR)

{

Sleep(500);

continue;

}

if (strlen(buf) != 0)

{

printf("%s\n", buf);

iStatus = RECV_OVER;

}

else

Sleep(100);

}

return 0;

}

//发送数据

unsigned __stdcall ThreadSend(void* param)

{

char buf[128] = { 0 };

int ret = 0;

while (1)

{

int c = getch();

if (c == 27) //ESC ASCII是27

{

memset(buf, 0, sizeof(buf));

printf("Please input the chat name:");

gets_s(buf);

char b[17] = { 0 };

sprintf(b, "#%s", buf);

ret = send(*(SOCKET*)param,b , sizeof(b), 0);

if (ret == SOCKET_ERROR)

return 1;

continue;

}

if(c == 72 || c == 0 || c == 68)//为了显示美观,加一个无回显的读取字符函数continue; //getch返回值我是经过实验得出如果是返回这几个值,则getch就会自动跳过,具体我也不懂。

printf("%s: ", userName);

gets_s(buf);

ret = send(*(SOCKET*)param, buf, sizeof(buf), 0);

if (ret == SOCKET_ERROR)

return 1;

}

return 0;

}

//连接服务器

int ConnectServer()

{

WSADATA wsaData = { 0 };//存放套接字信息

SOCKET ClientSocket = INVALID_SOCKET;//客户端套接字

SOCKADDR_IN ServerAddr = { 0 };//服务端地址

USHORT uPort = 18000;//服务端端口

//初始化套接字

if (WSAStartup(MAKEWORD(2, 2), &wsaData))

{

printf("WSAStartup failed with error code: %d\n", WSAGetLastError());

return -1;

}

//判断套接字版本

if (LOBYTE(wsaData.wVersion) != 2 || HIBYTE(wsaData.wVersion) != 2)

{

printf("wVersion was not 2.2\n");

return -1;

}

//创建套接字

ClientSocket = socket(AF_INET, SOCK_STREAM, IPPROTO_TCP);

if (ClientSocket == INVALID_SOCKET)

{

printf("socket failed with error code: %d\n", WSAGetLastError());

return -1;

}

//输入服务器IP

printf("Please input server IP:");

char IP[32] = { 0 };

gets_s(IP);

//设置服务器地址

ServerAddr.sin_family = AF_INET;

ServerAddr.sin_port = htons(uPort);//服务器端口

ServerAddr.sin_addr.S_un.S_addr = inet_addr(IP);//服务器地址

printf("connecting......\n");

//连接服务器

if (SOCKET_ERROR == connect(ClientSocket, (SOCKADDR*)&ServerAddr, sizeof(ServerAddr))) {

printf("connect failed with error code: %d\n", WSAGetLastError());

closesocket(ClientSocket);

WSACleanup();

return -1;

}

printf("Connecting server successfully IP:%s Port:%d\n",

IP, htons(ServerAddr.sin_port));

printf("Please input your UserName: ");

gets_s(userName);

send(ClientSocket, userName, sizeof(userName), 0);

printf("Please input the ChatName: ");

gets_s(chatName);

send(ClientSocket, chatName, sizeof(chatName), 0);

printf("\n\n");

_beginthreadex(NULL, 0, ThreadRecv, &ClientSocket, 0, NULL); //启动接收和发送消息线程_beginthreadex(NULL, 0, ThreadSend, &ClientSocket, 0, NULL);

for (int k = 0;k < 1000;k++)

Sleep(10000000);

closesocket(ClientSocket);

WSACleanup();

return 0;

}

int main()

{

ConnectServer(); //连接服务器

return 0;

}

基于java socket的聊天室项目文档

北京邮电大学软件学院 2010-2011 学年第 1学期实训项目文档 (每个项目小组一份) 课程名称:全日制研究生实训 项目名称:通信软件实训 项目完成人: 姓名:学号: 姓名:学号: 姓名:学号: 姓名:学号: 姓名:学号: 姓名:学号: 指导教师: 日期:2011年1月21日

基于java socket的聊天室实现 一 . 实训项目目的和要求(说明通过本项目希望达到的目的和要求) 目的:熟练掌握socket编程原理,并用java socket实现聊天室 要求:实现p2p和聊天室功能 二 . 实训项目开发环境(说明本项目需要的环境) 开发工具:Eclipse SDK Version: 3.5.2 和NetBeans 6.9.1 版本 系统:win7 三 . 实训项目内容(说明本项目的内容,如:问题分析、设计方案、算法、设计图等) 1.问题分析 网络编程中两个主要的问题一个是如何准确的定位网络上一台或多台 主机,另一个就是找到主机后如何可靠高效的进行数据传输。在TCP/IP协 议中IP层主要负责网络主机的定位,数据传输的路由,由IP地址可以唯一 地确定Internet上的一台主机。而TCP层则提供面向应用的可靠(tcp)的 或非可靠(UDP)的数据传输机制,这是网络编程的主要对象,一般不需要 关心IP层是如何处理数据的。目前较为流行的网络编程模型是客户机/服务 器(C/S)结构。即通信双方一方作为服务器等待客户提出请求并予以响应。 客户则在需要服务时向服务器提出申请。服务器一般作为守护进程始终运 行,监听网络端口,一旦有客户请求,就会启动一个服务进程来响应该客户, 同时自己继续监听服务端口,使后来的客户也能及时得到服务。 两类传输协议:TCP;UDP。TCP是Tranfer Control Protocol的简称, 是一种面向连接的保证可靠传输的协议。通过TCP协议传输,得到的是一个 顺序的无差错的数据流。发送方和接收方的成对的两个socket之间必须建 立连接,以便在TCP协议的基础上进行通信,当一个socket(通常都是server socket)等待建立连接时,另一个socket可以要求进行连接,一旦这两个socket连接起来,它们就可以进行双向数据传输,双方都可以进行发送或 接收操作。

基于ANDROID的socket聊天室服务器

package com.Server; import java.io.*; import https://www.360docs.net/doc/526977022.html,.*; import java.text.DateFormat; import java.text.SimpleDateFormat; import java.util.*; import javax.swing.JOptionPane; public class Server { ServerSocket ss = null; private String getnameString=null; boolean started = false; List clients = new ArrayList(); public static void main(String[] args) { String inputport = JOptionPane.showInputDialog("请输入服务器所用的端口:"); int port = Integer.parseInt(inputport); new Server().start(port); } public void start(int port) { try { ss = new ServerSocket(port); System.out.println("服务器启动"); started = true; } catch (BindException e) { System.out.println(" 端口已经被占用"); System.exit(0); } catch (IOException e) { e.printStackTrace(); } try { while (started) { Socket s = ss.accept(); Client c = new Client (s); System.out.println("a client is connected"); new Thread(c).start(); clients.add(c); } } catch (IOException e) {

基于Socket网络聊天系统的设计与实现

摘要 随着Internet的飞速发展,网络聊天以其操作简单、方便快捷、私密性好等优点已经迅速发展成为最普遍的网络交流方式之一,越来越受到人们的青睐,丰富了人们的网上生活。开发并实现具有自身特色的网络聊天系统具有实际应用价值。 本网络聊天系统基于Java应用程序设计,以Client/Server为开发模式,以Eclipse为开发环境,以MySQL为后台数据库,利用JDBC连接数据库。系统主要包括服务器模块和客户端模块,服务器模块能够对客户端发来的用户信息进行匹配、读取和转发;客户端模块能够进行注册、登录、聊天和文件传输。系统不但实现了点到点的聊天,还利用Java提供的Socket类和多线程功能,在单个程序中同时运行多个不同进程,从而实现多点对多点的聊天。 总之,该聊天系统具有开放性,实时性,多话题交错等特点,方便了人们网上交流。 【关键词】网络聊天服务器模块客户端模块 Socket

ABSTRACT With the rapid development of Internet, network chat with its simple operation, convenient and gond privacy has quickly become the most popular way of communication networks, more and more people like it, enrich people's online lives. Development and Realization of the network chat system with its own characteristics and has practical application value. The Internet chat system is based on Java application, designed by Client / Server as the development of models, as Eclipse development environment, MySQL as the backend database, and using JDBC to connect database. The system includes server modules and client modules, server module can match users'data, read and forward the information which is sent by client; client module to regist, login, chat and file transfer. The system not only achieves peer-to-peer chat, but also use the Java provids Socket class and multi-threading capabilities, in a single program run different processes at the same time, in order to achieve multipoint chat. In short, the chat system is open, real-time and multi-topic staggered features, easy for people to communicate online. 【Key words】Network Chat Client Module Server Module Socket 目录

JavaSocket实现多人聊天室

Java Socket实现多人聊天室---swing做UI 标签:socket聊天javaexception服务器string 2011-08-31 15:0620679人阅读评论(25)收藏举报分类: java(21) 版权声明:本文为博主原创文章,未经博主允许不得转载。 今天翻硬盘的workspace发现一个Java Socket实现多人聊天室的源码,不记得是什么时候的事情了,貌似不是我写的。但写得还不错, 至少算个有模有样的聊天室工具。我简单的修改了一下,拿出来跟大家分享一下,仅供参考。。。 界面是用swing写的,还不懒,简约大方。有图有真相:

正如上图所示,这个程序分为服务器端和客户端,说白了就是两个main class,用eclipse 直接运行之。。。。。 聊天室的设计思想是:在局域网下,利用socket进行连接通信,当服务器端启动的时候,利用Thread线程不停的等待客户端的链接;当有客户端开启连 接的时候,服务器端通过IO流反馈“上线用户”信息给客户端,客户端也使用线程不停的接收服务器的信息,从而实现多人在线聊天功能。 程序中有三个类,分别Server.java(服务器端)、Client(客户端)、User.java(javabean)。代码如下: Server.java(服务器端): [html]view plaincopy 1.import java.awt.BorderLayout; 2.import java.awt.Color; 3.import java.awt.GridLayout; 4.import java.awt.Toolkit; 5.import java.awt.event.ActionEvent;

计算机网络课设-基于TCP协议编程的网络聊天室

基于TCP协议编程的网络聊天室 设计内容:基于TCP协议编程的方式,编写程序模拟网络聊天室的运行过程。 设计要求: 1. 采用C/S模式,基于TCP协议编程的方式,使得各个用户通过服务器转发实现聊天的功能。 2. 分为两大模块:客户端模块和服务器端模块。 3. 客户端模块的主要功能: 1)登陆功能:用户可以注册,然后选择服务器登入聊天室。 2)显示用户:将在线用户显示在列表中。 3)接收信息:能接收其他用户发出的信息。 4)发送信息:能发出用户要发出的信息。 4.服务器端模块的主要功能: 1)检验登陆信息:检查登陆信息是否正确,并向客户端返回登陆信息,如 信息正确。就允许用户登陆。 2)显示在线状态:将该用户的状态发给各在线用户。 3)转发聊天信息:将消息转发给所有在线的用户。 5. 编程语言不限。 一、需求分析 此程序主要分为两部分:服务器端和客户端。 服务器端用于提供一个网络端口,等待客户端发出请求,登录到此服务端,然后进行网络通讯和消息的转发;客户端可通过服务器端的IP地址发送连接请求,然后登陆聊天室。在服务器端的成员列表栏中会显示在线的所有人名单,有人退出聊天室,成员列表会自动除名。整个程序的主体使用了CSocket类的方法,实现了网络通讯聊天。整个程序设计为两个部分:服务器(SpeakerServer)和客户端 (SpeakerClient) 。 多人聊天的关键在于要将每个客户端发送过来的消息分发给所有其他客户端,为了解决这个问题,在服务器程序中建立一个套接口链表,用来保存所有与客户端建立了连接的服务端口。 设计原理:服务器通过socket()系统调用创建一个Socket数组后(设定了接受连接客户的最大数目),与指定的本地端口绑定bind(),就可以在端口进

Java Socket网络编程--聊天室的实现(多线程实现无需等待对方响应版本)

一,服务端: package com.samael.socket; import java.io.BufferedInputStream; import java.io.BufferedOutputStream; import java.io.BufferedReader; import java.io.IOException; import java.io.InputStreamReader; import java.io.PrintWriter; import https://www.360docs.net/doc/526977022.html,.ServerSocket; import https://www.360docs.net/doc/526977022.html,.Socket; public class MyServer { class ThGetMsg extends Thread{ @Override public void run() { if(fromClient==null) return; while(true){ try { System.out.println("Message From Client:["+fromClient.readLine()+"]"); this.sleep(50); } catch (IOException e) { break; } catch (InterruptedException e) { e.printStackTrace(); } } } } public static BufferedReader fromClient=null; public static void main(String[] args) { try { //get server socket ServerSocket server=new ServerSocket(3166); //get socket from client Socket socket=server.accept(); System.out.println("The IP["+socket.getInetAddress()+"] is connected!");

基于socket简易聊天程序

简单的socket程序 2010-01-13 22:18 虽然很简单,但还是调试了很长时间。本科时候接触过socket——那个帅帅的刘 老师的课,现在重新再捡起来。 程序中专门建立一个FunThread线程用来接收数据,实现双向通信,也可以连续发送、连续接收。代码贴上来,如果还能保留VA View那样的颜色区别就好看 了,但是试了好几遍都不行 server: #include #include #define PORT 6000 //服务器端口 #define MSGSIZE 1024 //收发缓冲区的大小 #pragma comment(lib, "ws2_32.lib") //链接静态库 DWORD WINAPI FunThread(LPVOID); //创建一个线程,专门用来接收数据 SOCKET sClient; //连接所用套节字 SOCKET sListen; //监听套接字 SOCKADDR_IN client; //保存客户的地址信息 int iaddrSize = sizeof(SOCKADDR_IN); int main() { WSADATA wsaData; SOCKADDR_IN local; char s_Message[MSGSIZE]; //收发缓冲区 WSAStartup(0x0202, &wsaData); //Initialize Windows socket library sListen = socket(AF_INET, SOCK_STREAM, IPPROTO_TCP);//创建服务器监听套节字。TCP协议 local.sin_family = AF_INET; //AF_INET指明使用TCP/IP协议族 local.sin_port = htons(PORT);//指明连接服务器的端口号 local.sin_addr.s_addr = htonl(INADDR_ANY);//自动获取本机地址 bind(sListen, (struct sockaddr *)&local, sizeof(SOCKADDR_IN));//地址绑定到套接字

Linux下的Socket网络编程:一个简易聊天室的实现-徐慧军

Linux下的Socket网络编程:一个简易聊天室的实现-徐慧军

高级程序设计与应用实践 报告 一个简易聊天室的实现 姓名:徐慧军 学号:2121134 专业:电子与通信工程 学院:信息科学与技术学院 任课教师:廖晓飞 2013年05月02日

Linux下的Socket网络编程: ——一个简易聊天室的实现一、socket介绍 socket接口是TCP/IP网络的API,socket接口定义了许多函数或例程,程序员可以用它们来开发TCP/IP网络上的应用程序。要学Internet上的TCP/IP 网络编程,必须理解socket接口。 socket接口设计者最先是将接口放在Unix操作系统里面的。如果了解Unix 系统的输入和输出的话,就很容易了解socket了。网络的socket数据传输是一种特殊的I/O,socket也是一种文件描述符。socket也具有一个类似于打开文件的函数调用socket(),该函数返回一个整型的socket描述符,随后的连接建立、数据传输等操作都是通过该socket实现的。常用的socket类型有两种:流式socket (SOCK_STREAM)和数据报式socket(SOCK_DGRAM)。流式是一种面向连接的socket,针对于面向连接的TCP服务应用;数据报式socket是一种无连接的socket,对应于无连接的UDP服务应用。 二、Socket创建 socket函数原型为: #include #include int socket(int domain, int type, int protocol); 功能:调用成功,返回socket文件描述符;失败,返回-1,并设置errno 参数说明: domain指明所使用的协议族,通常为PF_INET,表示互联网协议族(TCP/IP 协议族; type参数指定socket的类型: SOCK_STREAM 提供有序、可靠、双向及基于连接的字节流

基于socket简易聊天程序毕业设计(论文)

简单的socket程序 虽然很简单,但还是调试了很长时间。本科时候接触过socket——那个帅帅的刘 老师的课,现在重新再捡起来。 程序中专门建立一个FunThread线程用来接收数据,实现双向通信,也可以连续发送、连续接收。代码贴上来,如果还能保留VA View那样的颜色区别就好看 了,但是试了好几遍都不行 server: #include #include #define PORT 6000 //服务器端口 #define MSGSIZE 1024 //收发缓冲区的大小 #pragma comment(lib, "ws2_32.lib") //链接静态库 DWORD WINAPI FunThread(LPVOID); //创建一个线程,专门用来接收数据 SOCKET sClient; //连接所用套节字 SOCKET sListen; //监听套接字 SOCKADDR_IN client; //保存客户的地址信息 int iaddrSize = sizeof(SOCKADDR_IN); int main() { WSADATA wsaData; SOCKADDR_IN local; char s_Message[MSGSIZE]; //收发缓冲区 WSAStartup(0x0202, &wsaData); //Initialize Windows socket library sListen = socket(AF_INET, SOCK_STREAM, IPPROTO_TCP);//创建服务器监听套节字。TCP协议 local.sin_family = AF_INET; //AF_INET指明使用TCP/IP协议族 local.sin_port = htons(PORT);//指明连接服务器的端口号 local.sin_addr.s_addr = htonl(INADDR_ANY);//自动获取本机地址 bind(sListen, (struct sockaddr *)&local, sizeof(SOCKADDR_IN));//地址绑定到套接字

Linux C语言 socket编程 聊天室 可移植到arm开发板

sockets聊天室 1.1介绍 包括一个客户端和一个服务器。可实现多人聊天和两人一对一单独聊天。 1.2开发环境和工具 Linux gcc 1.3程序设计 服务器: 1. 声明一个client结构体,包含用户自己的socket描述符mid,自己的用户名name以及 与自己聊天对象的Socket描述符fid(默认是-1,即公共聊天室)。并定义一个结构体数组。 2. 服务器新建一个socket设置默认的ip为自动获取,调用bind()函数绑定服务器socket 与ip。 3. 开启listen()监听客户端的连接请求。 4. 在while循环里,用accept()等待连接,连接成功后,把accept()返回的socket描述 符存入client结构体数组中。 5. 每成功新建一个连接,就创建一个对应的子线程,接收并转发消息。 6. 定义void rec_snd(int n)这个函数,用于接收和转发消息。可选择公共聊天室和私聊, 私聊需要正确输入对方的名字。连接建立以后就可以发送消息。当接收的消息为bye 时,断开当前连接,如果是一对一私聊,一方断开另一方自动转入公共聊天室。 客户端: 1.新建一个socket,并与ip,端口进行绑定。 2.调用connect连接服务器。连接成功后新建一个线程用于发送消息, 主线程在while中调用read()接收服务器消息。 3.Snd()函数用于向服务器发送消息。 4._select()函数用于选择功能。 1.4应用演示 服务器端成功开启等待连接:

当有客户端连接时,会显示ip端口,socket标识符信息。客户端成功连接上服务器时会收到提示输入用户名: 输入姓名后会提示选择功能:

基于Socket的聊天室(C#版)

一、服务器/客户端聊天室模型 聊天室客户端(商用PC) 服务器 聊天室客户端 (其他) 聊天室客户端(笔记 本) 其他服务器 1.首先启动聊天室服务器,使得TcpListener开始监听端口,此时TcpListener 会进入Pending状态,等待客户端连接; 2.其次,当有客户端连接后,通过AccepSocket返回与客户端连接的Socket对象,然后通过读写Socket对象完成与聊天室客户端的数据传输。聊天室客户端成功启动后,首先创建一个Socket对象,然后通过这个Socket对象连接聊天室服务器,连接成功后开通Socket完成数据的接收和发送处理。 二、系统功能设计 本设计为一个简单的聊天室工具,设计基本的聊天功能,如聊天、列表维护等。系统主要为两大块:聊天室服务器及聊天室客户端。 服务器界面设计如下:

客户端界面设计如下:

三、聊天协议的应答 A—网络—B 主机与主机通信主要识别身份(标识设备用IP)及通信协议 网络应用程序——端口号——接收数据 注:1.IP地址是总机,端口号是分机(传输层) 2.端口号为16位二进制数,范围0到65535,但实际编程只能用1024以上 端口号 Socket编程 首先,我们了解常用网络编程协议。我们用得最多的协议是UDP和TCP,UDP是 不可靠传输服务,TCP是可靠传输服务。UDP就像点对点的数据传输一样,发送 者把数据打包,包上有收信者的地址和其他必要信息,至于收信者能不能收到,UDP协议并不保证。而TCP协议就像(实际他们是一个层次的网络协议)是建立在 UDP的基础上,加入了校验和重传等复杂的机制来保证数据可靠的传达到收信 者。一个是面向连接一个无连接,各有用处,在一些数据传输率高的场合如视频 会议倾向于UDP,而对一些数据安全要求高的地方如下载文件就倾向于TCP。 Socket————网络应用程序 电话机————访问通信协议 聊天协议的应答: 聊天状态:CLOSED和CONNECTED状态 执行CONN命令后进入CONNECTED状态,执行下列命令: CONN:连接聊天室服务器

软件工程课程设计方案Socket聊天系统

目录 1.前言 (1) 2.需求分析 (2) 2.1系统的功能需求 (2) ................................................................................................................................... 错误!未定义书签。 ................................................................................................................................... 错误!未定义书签。 ................................................................................................................................... 错误!未定义书签。 ................................................................................................................................... 错误!未定义书签。 ................................................................................................................................... 错误!未定义书签。 2.2非功能需求: (2) ................................................................................................................................... 错误!未定义书签。 2.3用例分析 (2) ................................................................................................................................... 错误!未定义书签。 ................................................................................................................................... 错误!未定义书签。 ................................................................................................................................... 错误!未定义书签。 3.总体设计 (3) 3.1TCP服务器设置 (3) 3.2分析类图 (4) 3.3顺序图 (5) ................................................................................................................................... 错误!未定义书签。 ................................................................................................................................... 错误!未定义书签。 3.3协作图 (5) ................................................................................................................................... 错误!未定义书签。 ................................................................................................................................... 错误!未定义书签。 4.详细设计 (5) 4.1客户端设计 (5) 4.2服务端设计 (6) 4.3多线程设计 (6) 5.代码实现 (7) 5.1服务端设计 (7) 5.2客户端设计 (9) 5.3多线程 (12)

应用C++多人聊天室的构建

多人聊天室的构建 ——基于CAsyncSocket 类的Windows Sockets编程 [提要]本章介绍了Socket的工作机制和基于CAsyncSocket 类的Sockets编程的基本方法。通过一个应用实例,编写服务端和客户端代码,实现多人之间信息传递。 一、TCP/IP 体系结构与特点 1、TCP/IP体系结构 TCP/IP协议实际上就是在物理网上的一组完整的网络协议。其中TCP是提供传输层服务,而IP则是提供网络层服务。TCP/IP包括以下协议:(结构如图1.1) (图1.1) IP:网间协议(Internet Protocol),负责主机间数据的路由和网络上数据的存储。同时为ICMP,TCP,UDP提供分组发送服务。用户进程通常不需要涉及这一层。 ARP:地址解析协议(Address Resolution Protocol),此协议将网络地址映射到硬件地址。 RARP:反向地址解析协议(Reverse Address Resolution Protocol),此协议将硬件地址映射到网络地址 ICMP:网间报文控制协议(Internet Control Message Protocol),此协议处理信关和主机的差错和传送控制。 TCP:传送控制协议(Transmission Control Protocol),这是一种提供给用户进程的可靠的全双工字节流面向连接的协议。它要为用户进程提供虚电路服务,并为数据可靠传输建立检查。(注:大多数网络用户程序使用TCP) UDP:用户数据报协议(User Datagram Protocol),这是提供给用户进程的无连接协议,用于传送数据而不执行正确性检查。

Socket和多线程编程的聊天程序实现

一、课题内容和要求 1.课题内容 基于Socket和多线程编程的聊天程序实现 2.课题要求 网络聊天程序设计非常复杂,允许多个人同时聊天更加需要多线程技术的支持,请实现一个简单的多线程网络聊天程序模拟。 二、设计思路分析 1. 在网络越来越发达的今天,人们对网络的依赖越来越强,网络聊天已经成了许多人生活中必不可少的一部分,基于这样的需求,出现了许多网络聊天通信工具,像QQ,MSN 等等,但是人们已经不再满足于单一的两个人之间的聊天,而是对多人同时聊天产生了兴趣,于是出现了网络聊天室,不同地方的人可以在那个虚拟的聊天室里面热烈聊天。基于这样的想法,我们用JAVA设计一个多人同时聊天的小程序,用Socket编程实现网络通讯,面向连接的,采用多线程的实现技术。 2. 在程序中,可以设置加入连接的最大数目,通过更改IP地址和端口号,成为不同的客户端,与服务器端连接,进行多用户聊天。 % 3. 为方便用户交互,我们采用图形化的用户界面。实现了好友添加,消息收发、显示等基本功能。 三、概要设计 该网络聊天程序大致分为三个主要部分:客户端、服务器端和用户图形界面。各个部分的初步设计思想、流程及存储结构如下: 1. 程序整体框架:主程序监听一端口,等待客户接入;同时构造一个线程类,准备接管会话。当一个Socket会话产生后,将这个会话交给线程处理,然后主程序继续监听。 打开Socket 命名 ! 监听端口 建立连接 收发消息 关闭连接 ¥ 打开Socket 连接服务器 收发消息

; 关闭连接 服务器端程序 客户端程序 2. 客户端(Client) 客户端,使用Socket对网络上某一个服务器的某一个端口发出连接请求,一旦连接成功,打开会话;会话完成后,关闭Socket。客户端不需要指定打开的端口,通常临时的、动态的分配一个端口。 ? 3. 服务器端(Server) 服务器端,使用ServerSocket监听指定的端口,端口可以随意指定(由于1024以下的端口通常属于保留端口,在一些操作系统中不可以随意使用,所以建议使用大于1024的端口),等待客户连接请求,客户连接后,会话产生;在完成会话后,关闭连接。 4. 用户图形界面 用户图形界面方便程序与用户的交互,多个用户参加,完成会话功能,具体的设计要方便用户的使用,直观清晰,简洁明了,友好美观。 5. 存储结构 四、详细设计 代码分服务器端、客户端、和用户图形界面三部分,分别如下: 1.服务器端 服务器端主要是使用ServerSocket类,相当于服务器Socket,用来监听试图进入的连接,当新的连接建立后,该类为他们实例化一个Socket对象,同时得到输入输出流,调用相应方法完成会话。

简单的多人聊天(C#.Socket)

/********************************8chatserver:*************************************************/ using system; using system.drawing; using system.collections; using https://www.360docs.net/doc/526977022.html,ponentmodel; using system.windows.forms; using system.data; using system.threading; using https://www.360docs.net/doc/526977022.html,.sockets; using https://www.360docs.net/doc/526977022.html,; namespace chat_server { ///

/// form1 的摘要说明。 /// public class form1 : system.windows.forms.form { /// /// 必需的设计器变量。 /// private https://www.360docs.net/doc/526977022.html,ponentmodel.container components = null; static int listenport=6666; socket clientsocket; private system.windows.forms.listbox lbclients; arraylist clients; private system.windows.forms.button button1; thread clientservice; private https://www.360docs.net/doc/526977022.html,bel label1; thread threadlisten; public form1() { initializecomponent();

基于Socket的局域网通信工具的设计与实现的方法

摘要 随着计算机科学和Internet的飞速发展,网上聊天已成为人们相互交流的一中方式,与E-mail、电话相比,聊天服务更具有实时性和有效性。网络版的聊天软件种类繁多,如QQ、OICQ、MSN等,实现随时随地上网聊天,给人们带来了很大的方便。但是这些聊天软件也存在以下不足:用户必须连接Internet;用户在工作时容易沉迷于网络聊天。为了方便单位企业内部的信息交流,避免企业内部员工使用类似QQ等软件泄露内部信息,减少不必要的财力和人力资源浪费,开发一个局域网聊天软件是非常必要的。 通过对局域网络通信的学习研究,本文介绍了局域网通信和实现聊天器基本通信功能的流程,并编写了一个基于Winsock的局域网络聊天器系统。本系统是运行于MFC 平台上的Winsock局域网聊天软件,该聊天软件采用C/S结构,包括服务器和客户端两个模块,客户端通过服务端进行通信。服务器模块主要实现了服务器的配置和数据的传递;客户端模块主要实现了用户注册、登录、文字聊天和文件传送等功能。该软件采用多线程技术支持多用户操作,并采用相关技术进行了优化,加快了文字传递速度。主要用到了Winsock编程技术、TCP/IP协议、多线程技术、数据库存取技术和各种控件编程技术。 本文主要分为六个章节,第一章概括的说明聊天器的背景及应用。第二章阐述实现局域网络聊天器系统所用到的主要技术。第三章根据聊天器的设计实现进行需求分析。第四章详细描述了本系统各个模块的设计。第五章重点介绍各个模块的实现和测试。第

六章是结束语,总结毕业设计中遇到的问题和自己的收获,感谢给予指导和帮组的老师和同学。 关键词:局域网;TCP/IP协议;Winsock;多线程

基于websocket和java的多人聊天室

最新基于websocket与java的多人聊天室实现架构 html5+websocket+javaEE7+tomcat8 JavaEE7 最新的websocket1.0 API Tomcat8开始支持websocket1.0 API 【Tomcat implements the Java WebSocket 1.0 API defined by JSR-356】 在编写代码之前你要导入javaEE7的jar包以便使用websocket API,将此项目部署到tomcat8里面。 具体代码如下: Java端: ChatAnnotation类; 使用的是注解的方式。 package websocket.chat;

import java.io.IOException; import java.util.Set; import java.util.concurrent.CopyOnWriteArraySet; import java.util.concurrent.atomic.AtomicInteger; import javax.websocket.OnClose; import javax.websocket.OnError; import javax.websocket.OnMessage; import javax.websocket.OnOpen; import javax.websocket.Session; import javax.websocket.server.ServerEndpoint; import org.apache.juli.logging.Log; import org.apache.juli.logging.LogFactory; import util.HTMLFilter; @ServerEndpoint(value = "/websocket/chat") public class ChatAnnotation { private static final Log log = LogFactory.getLog(ChatAnnotation.class); private static final String GUEST_PREFIX = "Guest"; private static final AtomicInteger connectionIds = new AtomicInteger(0); private static final Set connections = new CopyOnWriteArraySet<>(); private final String nickname; private Session session; public ChatAnnotation() { nickname = GUEST_PREFIX + connectionIds.getAndIncrement(); } @OnOpen public void start(Session session) { this.session = session; connections.add(this); String message = String.format("* %s %s", nickname, "has joined."); broadcast(message);

“基于Socket的网络聊天系统的设计与实现”课程设计报告

《计算机网络课程设计报告》 学院:计算机科学学院 专业:计算机科学与技术 班级:08级01班 姓名: 学号: 小组成员: A B C D E F 2011-7-13

项目内容:基于Socket的网络聊天系统的设计与实现 实验目的:基于Socket套接口,实现网络聊天系统的设计与实现,让我们掌握Socket的编程技术及网络服务的技术,让同学们更加深刻的了解,并掌握这方面的知识。 实验环境:操作系统:windows2000或windows2003; 内存:256M以上; 基于eclipse的JAVA运行环境。 设计方案:首先,我们知道此应用软件需实现网络中多台主机的信息互通,实现语言文字得互聊,因此涉及到主机网络互联的问题,所以必须会应用到网络协议,可以 用UDP或TCP。 其次,既然要求设计基于Socket的网络聊天系统,那就必须对Socket有一个 充分的了解。 最后,不管运用何种语言设计此程序,都要求对该语言有一个透彻的了解,并 能运用自如。 实现流程:启动电脑,打开能运行该程序的环境,必须保证代码的正确性; 进行窗体框架的设计,实现网络连接,并达到网络聊天的功能; 在以上步骤的成功进行下达到设计要求的基于S o c k e t s的局域网内聊 天系统的函数实现的目的。 结果及分析:程序运行以后,经过局域网内测试,实现了在局域网内的好友添加,聊天等功能,基本上完成了本实验的全部要求。但 由于时间仓促,再加上本人水平有限,对这方面的知识还 有所欠缺,经过这次课程设计,对此有了一个很大的提高。 源程序;

一 Client端程序代码 package wangluo; import java.awt.BorderLayout; import java.awt.event.ActionEvent; import java.awt.event.ActionListener; import java.io.DataInputStream; import java.io.DataOutputStream; import javax.swing.JFrame; import javax.swing.JTextField; public class Client implements ActionListener { private JTextField jtf = new JTextField("", 20); JFrame jf = new JFrame("不用注册直接登陆"); public Client() { jf.setLayout(new BorderLayout()); jf.add(jtf, BorderLayout.NORTH); jtf.addActionListener(this); jf.pack(); jf.setLocation(500, 300); jf.setResizable(false); jf.setVisible(true); jf.setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE); } @Override public void actionPerformed(ActionEvent e) { jf.dispose();

相关文档
最新文档