Socket通信-accept+多线程

    偶然的机会,重新写了一下windows下socket通信的比较基础的代码,
    太久没有接触socket以及多线程,查了不少博客,但是发现大部分内容比较陈旧,
    所以决定写一篇博客,顺便自己总结一下。

内容简介

  • 网络通信基本函数介绍
  • C++11多线程简介
  • socket通信tcp版本
  • socket通信udp版本

网络通信基本函数介绍

tcp连接模式下
客户端流程
1.创建socket(套接字)
    socket(int af, int type, int protocol)
    第一个参数用来说明网络协议类型,tcp/ip协议只能用AF_INET
    第二个参数:socket通讯类型(tcp,udp等)
    第三个参数:与选择的通讯类型有关
2.向服务器发起连接
    SOCKADDR_IN 声明套接字类型
        sin_family 协议家族
        sin_port 通信端口
        sin_addr 网络ip

    htons 将整型类型转换成网络字节序
    htonl 将长整型转换成网络字节序

    inet_pton(int af, char * str, pvoid addrbuf) 将点分十进制ip地址转换成网络字节
        第一个参数:协议家族
        第二个参数:点分十进制ip地址,例如:"127.0.0.1"
        第三个参数:sin_addr

    inte_ntop (int af, pvoid addrbuf, char *str, size_t len) 将网络字节序转换成点分十进制ip地址
        第一个参数:协议家族
        第二个参数:sin_addr
        第三个参数:存储ip地址的字符串
        第四个参数:字节单位长度

    connect(socket s, const sockaddr *name, int namelen)
        第一个参数:创建的套接字
        第二个参数:要链接的套接字地址
        第三个参数:单位长度

3.client与server通信
    send(socket s, char * str, int len, int flag)
        第一个参数:本机创建的套接字
        第二个参数:要发送的字符串
        第三个参数:发送字符串长度
        第四个参数:会对函数行为产生影响,一般设置为0

    recv(socket s, char * buf, int len,int flag)
        第一个参数:本机创建的套接字
        第二个参数:接受消息的字符串
        第三个参数:允许接收字符串的最大长度
        第四个参数:会对函数行为产生影响,一般设置为0

4.释放套接字
    closesocket 释放套接字
服务端流程
1.创建套接字
2.将套接字与本地的ip和端口绑定
    bind(socket s, const sockaddr *name, int namelen)
        第一个参数:创建的套接字
        第二个参数:要绑定的信息
        第三个参数:套接字类型单位长度
3.设置为监听状态
    listen(socket s, int num)
        第一个参数:要监听的socket(套接字)
        第二个参数:等待连接队列的最大长度
4.等待客户请求到来;当请求到来后,接受连接请求,返回一个新的对应于此次连接的套接字
    accept(int socket, sockaddr *name, int *addrlen)
        第一个参数,是一个已设为监听模式的socket的描述符。
        第二个参数,是一个返回值,它指向一个struct sockaddr类型的结构体的变量,保存了发起连接的客户端得IP地址信息和端口信息。
        第三个参数,也是一个返回值,指向整型的变量,保存了返回的地址信息的长度。
        accept函数返回值是一个客户端和服务器连接的SOCKET类型的描述符,在服务器端标识着这个客户端。
5.相互通信
6.断开连接
udp通信
客户端
1.创建套接字
2.绑定服务器ip和port已经协议家族
3.相互通信
    sendto(socket s, const char * buf, int len, int flags, const sockaddr *to,int tolen)
        第一个参数:创建的套接字
        第二个参数:要发送的字符串
        第三个参数:要发送的字符串长度
        第四个参数:影响函数的行为,一般为0
        第五个参数:远端套接字信息
        第六个参数:套接字单位长度

    recvfrom(socket s, char * buf, int len, int flags, const sockaddr *to,int tolen)
        第一个参数:创建的套接字
        第二个参数:存储接收的字符串
        第三个参数:可接受的最大字符串长度
        第四个参数:影响函数的行为,一般为0
        第五个参数:远端套接字信息
        第六个参数:套接字单位长度
4.释放套接字
服务端
1.创建套接字
2.绑定本地的端口,ip,协议家族信息
3.通信
4.释放连接

C++11多线程简介

我们在socket通信过程中经常会有多个客户端向服务端发起请求的问题,在tcp模式下,会发生阻塞,解决的办法有accetp+多线程或者select+accept模式,这篇博客主要对前者就行详解,在查阅资料的过程中,我发现网上好多的博客介绍的多线程机制都是多年以前的方式,使用起来特别麻烦,比如pthread这种库,其实C++11以后,官方就已经将线程库封装了起来,我们只需要声明一下即可,该库thread

#include<thread>    
定义 std::thread xxx;
构造 std::thread(func, ...)
等待线程结束 xxx.join()   

socket通信tcp版本

服务器端
// ServerTcp.cpp : 定义控制台应用程序的入口点。
//

#include "stdafx.h"
#pragma comment(lib, "ws2_32.lib")
#include <Winsock2.h>
#include <WS2tcpip.h>
#include <stdio.h>
#include <string.h>
#include <stdlib.h>
#include <thread>

void func(SOCKET arg, SOCKADDR_IN client_addr, int pos)
{
    char recvBuf[128];
    char sendBuf[128];
    char tempBuf[256];
    int sockConn = arg;
    while (true)
    {
        // 从客户端接收消息
        printf(
评论 2
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值