• 协议之间的关系

  • socket在哪

  • socket是什么

 Socket是应用层与TCP/IP协议族通信的中间软件抽象层,它是一组接口。在设计模式中,Socket其实就是一个门面模式,它把复杂的TCP/IP协议族隐藏在Socket接口后面,对用户来说,一组简单的接口就是全部,让Socket去组织数据,以符合指定的协议。

  门面模式,用自己的话说,就是系统对外界提供单一的接口,外部不需要了解内部的实现。

  • socket编程的基本流程

tcp通信实现多线程连接与群聊

服务器端

  • 定义端口以及本地ip地址

    1. #define port 9876
    2. #define ip_addr "192.168.1.102"
  • 创建事件以及互斥量

    1. HANDLE event;//事件
    2. HANDLE mutex = NULL;
    1. event = CreateEvent(NULL, TRUE, FALSE, NULL);//第二个参数TRUE表示手动复位
    2. mutex = CreateMutex(NULL, FALSE, NULL);//互相排斥
  • 接收连接

    1. //接受连接
    2. void recv_connect(void *p)
    3. {
    4. WSADATA WSA;//对比版本
    5.  
    6. SOCKET client,sever;//客户端
    7.  
    8. //本地地址信息,以及连接的客户端地址信息
    9. struct sockaddr_in localeaddr,clientaddr;
    10. int addrlength = ;
    11. HANDLE hthread1 = NULL;//线程句柄
    12. HANDLE hthread2 = NULL;
    13. HANDLE hthread3 = NULL;
    14. int Ret = ;
    15. char senbuf[] = { };
    16.  
    17. //对比版本
    18. if (WSAStartup(MAKEWORD(, ), &WSA) != )
    19. {
    20. puts("版本不一致,通信失败");
    21. system("pause");
    22. return;
    23. }
    24. //创建通信
    25. sever = socket(AF_INET, SOCK_STREAM, );
    26. if (sever == INVALID_SOCKET)
    27. {
    28. puts("服务器创建失败");
    29. system("pause");
    30. return;
    31. }
    32. //设置服务器结构体信息
    33. localeaddr.sin_family = AF_INET;
    34. localeaddr.sin_addr.s_addr = inet_addr(ip_addr);
    35. localeaddr.sin_port = htons(port);
    36. memset(localeaddr.sin_zero, 0x00, );//清零
    37. //与socket绑定
    38. Ret = bind(sever, (struct sockaddr*)&localeaddr, sizeof(localeaddr));
    39. if (Ret != )
    40. {
    41. puts("绑定失败");
    42. system("pause");
    43. return;
    44. }
    45. Ret = listen(sever, );
    46. if (Ret != )
    47. {
    48. puts("监听失败");
    49. system("pause");
    50. return;
    51. }
    52. puts("服务器启动");
    53.  
    54. while ()
    55. {
    56. addrlength = sizeof(clientaddr);//获取长度
    57. //接受客户端连接,信息存放在clientaddr中
    58. client = accept(sever, (struct sockaddr*) &clientaddr, &addrlength);
    59. if (client == INVALID_SOCKET)
    60. {
    61. puts("接收失败");
    62. system("pause");
    63. return;
    64. }
    65. printf("\n客户端连接%s 端口号:%d\n", inet_ntoa(clientaddr.sin_addr), clientaddr.sin_port);
    66. //创建写的线程
    67. hthread3 = CreateThread(NULL, , clientthreadwrite, (void*)client, , NULL);
    68. }
    69.  
    70. //关闭socket
    71. closesocket(sever);
    72. closesocket(client);
    73. WSACleanup();
    74. }
  • 向客户端发送消息的多线程函数

    1. //创建线程向客户端发送消息
    2. DWORD WINAPI clientthreadwrite(void *p)
    3. {
    4. SOCKET client = (SOCKET)p;//数指针类型转换
    5. int Ret = ;
    6.  
    7. while ()
    8. {
    9. WaitForSingleObject(event, INFINITE);//等待事件
    10. WaitForSingleObject(mutex, INFINITE);
    11.  
    12. if (strlen(sendbuf) != )
    13. {
    14. //发送信息
    15. Ret = send(client, sendbuf, strlen(sendbuf), 0);
    16. }
    17. ReleaseMutex(mutex);
    18. ResetEvent(event);//手动复位
    19. }
    20. }
  • 从客户端接收消息的多线程函数

    1. DWORD WINAPI clientthreadread(void *p)
    2. {
    3. //数指针类型转换
    4. SOCKET client = (SOCKET)p;
    5. int Ret = ;
    6. char receivebuf[];
    7.  
    8. while ()
    9. {
    10. //清零
    11. memset(receivebuf, , );
    12. //读取
    13. Ret = recv(client, receivebuf, 256, 0);
    14. if (Ret == SOCKET_ERROR)
    15. {
    16. puts("客户端send失败");
    17. break;
    18. }
    19. printf("\n收到%s,", receivebuf);
    20. //进入临界区
    21. WaitForSingleObject(mutex, INFINITE);
    22. memset(sendbuf, , );
    23. //全局变量,锁定
    24. strcpy(sendbuf, receivebuf);
    25. ReleaseMutex(mutex);
    26. //通知
    27. SetEvent(event);
    28. }
    29. return ;
    30. }

      

  • main函数
    1. void main()
    2. {
    3. event = CreateEvent(NULL, TRUE, FALSE, NULL);//第二个参数TRUE表示手动复位
    4. mutex = CreateMutex(NULL, FALSE, NULL);//互相排斥
    5.  
    6. _beginthread(recv_connect, , NULL);
    7.  
    8. Sleep();
    9. while ()
    10. {
    11. printf("请输入要发送的信息:");
    12. scanf("%s", sendbuf);
    13. SetEvent(event);
    14. }
    15. system("pause");
    16. }

客户端

  1. #define _CRT_SECURE_NO_WARNINGS
  2. #include<stdio.h>
  3. #include<stdlib.h>
  4. #include <winsock.h>
  5. #pragma comment(lib,"ws2_32.lib")
  6.  
  7. //定义端口号
  8. #define port 9876
  9. //要连接的ip地址
  10. #define ip_addr "192.168.1.102"
  11.  
  12. void main()
  13. {
  14. //对比版本
  15. WSADATA WSA;
  16. //客户端套接字
  17. SOCKET client;
  18. //服务器信息
  19. struct sockaddr_in severaddr;
  20. //线程句柄
  21. HANDLE hthread = NULL;
  22. //保存连接信息
  23. int Ret = ;
  24. char senbuf[] = { };
  25.  
  26. if (WSAStartup(MAKEWORD(,),&WSA)!=)
  27. {
  28. puts("版本不一致,通信失败");
  29. system("pause");
  30. return;
  31. }
  32. //创建socket
  33. client = socket(AF_INET, SOCK_STREAM, );
  34. if (client == INVALID_SOCKET)
  35. {
  36. puts("客户端创建失败");
  37. system("pause");
  38.  
  39. }
  40. //设置服务器信息
  41. severaddr.sin_family = AF_INET;
  42. //设置地址
  43. severaddr.sin_addr.s_addr = inet_addr(ip_addr);
  44. //端口
  45. severaddr.sin_port = htons(port);
  46. //清空
  47. memset(severaddr.sin_zero, 0x00, );
  48.  
  49. //连接
  50. Ret = connect(client, (struct sockaddr*) &severaddr, sizeof(severaddr));
  51. if (Ret!=)
  52. {
  53. puts("客户端链接失败");
  54. system("pause");
  55. }
  56. while ()
  57. {
  58. //printf("请输入向服务器发送的消息:");
  59. //scanf("%s", senbuf);//输入
  60. //Ret = send(client, senbuf, strlen(senbuf), 0);//发送
  61. //if (Ret==SOCKET_ERROR)
  62. //{
  63. // puts("客户端send失败");
  64. // system("pause");
  65. //}
  66. char receivebuf[];
  67. memset(receivebuf, , );//清零
  68. Ret = recv(client, receivebuf, , );
  69. printf("收到客户端发送的消息:%s\n", receivebuf);
  70. }
  71.  
  72. closesocket(client);
  73. WSACleanup();
  74. }

102.tcp实现多线程连接与群聊的更多相关文章

  1. 104.tcp多线程读写实现群聊

    客户端: #define _CRT_SECURE_NO_WARNINGS #include<stdio.h> #include<stdlib.h> #include <w ...

  2. C/S模型之TCP群聊

    说明:利用TCP协议和多线程实现群聊功能.一个服务器,多个客户端(同一个程序多次启动).客户端向服务端发送数据,由服务端进行转发到其他客户端. /服务端 // WSASever.cpp : 定义控制台 ...

  3. Strophe.js连接XMPP服务器Openfire、Tigase实现Web私聊、群聊(MUC)

    XMPP(Extensible Messaging and Presence Protocol)是一种网络即时通讯协议,它基于XML,具有很强的扩展性,被广泛使用在即时通讯软件.网络游戏聊天.Web聊 ...

  4. Java-->实现群聊功能(C/S模式--TCP协议)

    --> Java 对TCP协议的支持: --> java.net包中定义了两个类ServerSocket 和Socket ,分别用来实现双向连接的server 端和client 端. -- ...

  5. [Python 网络编程] TCP编程/群聊服务端 (二)

    群聊服务端 需求分析: 1. 群聊服务端需支持启动和停止(清理资源); 2. 可以接收客户端的连接; 接收客户端发来的数据 3. 可以将每条信息分发到所有客户端 1) 先搭架子: #TCP Serve ...

  6. Java 网络编程 -- 基于TCP 实现聊天室 群聊 私聊

    分析: 聊天室需要多个客户端和一个服务端. 服务端负责转发消息. 客户端可以发送消息.接收消息. 消息分类: 群聊消息:发送除自己外所有人 私聊消息:只发送@的人 系统消息:根据情况分只发送个人和其他 ...

  7. websocket实现群聊和单聊(转)

    昨日内容回顾 1.Flask路由 1.endpoint="user" # 反向url地址 2.url_address = url_for("user") 3.m ...

  8. JAVA 网络编程 - 实现 群聊 程序

    在实现 这个 程序之前, 我们 需要 了解 一些 关于 Java 网络 编程 的 知识. 基本 的 网络知识: 网络模型 OSI (Open System Interconnection 开放系统互连 ...

  9. java基于socket的网络通信,实现一个服务端多个客户端的群聊,传输文件功能,界面使用Swing

    最近在复习java的io流及网络编程.但复习写那些样板程序总是乏味的.便准备写个项目来巩固.想来想去还是聊天项目比较好玩.如果日后完成的比较好自己也可以用(哈哈哈).并且自己后面也要继续巩固java多 ...

随机推荐

  1. ORA-01659: 无法分配超出 7 的 MINEXTENTS

    plsql连接出错:ORA-01659: 无法分配超出 7 的 MINEXTENTS (在表空间 PERFSTAT 中) 从 Oracle Database 10g Enterprise Editio ...

  2. [工具] UltraEdit使用技巧汇总

    ltraEdit是一套功能强大的文本编辑器,可以编辑文本.十六进制.ASCII码,可以取代记事本,内建英文单字检查.C++及VB指令突显,可同时编辑多个文件,而且即使开启很大的文件速度也不会慢.说到编 ...

  3. angular-cli6使用ng serve --o 控制台报错Invalid Host Header

    angular-cli6使用ng serve --o 运行创建的项目,能正常访问,但是控制台一直在报错,点击报错能看到是因为webpack的webpack-dev-server里报的错, 看到网上介绍 ...

  4. 【Django】视图系统

    目录 FBV 与 CBV 给视图加装饰器 使用装饰器装饰CBV 关于dispatch()方法 Request对象 与 Response对象 request对象 response对象 @ *** 一个视 ...

  5. JavaScript-原型&原型链&原型继承

    JavaScript-原型&原型链&原型继承 JavaScript的原型是一个重要的知识点,很多扩展应用都是从原型出发的.要说原型,我们先简单说一下函数创建过程.上一篇文章用闭包实现类 ...

  6. CCF模拟题 最大的矩形

    最大的矩形 时间限制: 1.0s 内存限制: 256.0MB     问题描述 在横轴上放了n个相邻的矩形,每个矩形的宽度是1,而第i(1 ≤ i ≤ n)个矩形的高度是hi.这n个矩形构成了一个直方 ...

  7. CF(438D) The Child and Sequence(线段树)

    题意:对数列有三种操作: Print operation l, r. Picks should write down the value of . Modulo operation l, r, x. ...

  8. mysql通过字段凝视查找字段名称

    有时候表的字段太多.仅仅是大致记得表的凝视,想通过字段凝视查找字段名称,能够用例如以下语句: SELECT COLUMN_NAME,column_comment FROM INFORMATION_SC ...

  9. CCNA Cloud CLDFND 210-451 QUIZ: Server Virtualization

    Author:海峰 http://weibo.com/344736086 http://yanheven.github.io/ http://blog.csdn.net/yanheven1 1.Whi ...

  10. leetCode 27.Remove Element (删除元素) 解题思路和方法

    Remove Element Given an array and a value, remove all instances of that value in place and return th ...