目录

1.ip:端口  TCP/IP协议

2.socket 头文件  sys/socket.h

3.字节序

4.ip地址转换函数

5.sockaddr和sockaddr_in

6.服务器端基本函数 bind listen accept

7.客户端基本函数  connect

8.send 和 recv

8.多线程

9.通信流程

10.多线程并发样例程序


1.ip:端口  TCP/IP协议

AF_INET             IPv4
 AF_INET6            IPv6

SOCK_STREAM  tcp协议

2.socket 头文件  sys/socket.h 

套接字对应程序猿来说就是一套网络通信的接口,使用这套接口就可以完成网络通信。
网络通信的主体主要分为两部分:客户端和服务器端

int socket(int domain, int type, int protocol);

(1)在参数表中,domain指定使用何种的地址类型,比较常用的有:

PF_INET, AF_INET: Ipv4网络协议;

PF_INET6, AF_INET6: Ipv6网络协议。

(2)type参数的作用是设置通信的协议类型,可能的取值如下所示:

SOCK_STREAM: 提供面向连接的稳定数据传输,即TCP协议。

(3)一般取0即可

3.字节序

ittle-Endian -> 主机字节序 (小端)
    Big-Endian -> 网络字节序 (大端)
    
    头文件:#include <arpa/inet.h> //包含 sys/socket.h
    uint16_htons(uint16_t hostshort) //短整形 主机字节序 --> 网络字节序
    uint32_htonl(uint32_t hostlong) //长整形  主机字节序 -->网络字节序

uint16_ntohs(uint16_t netshort) //短整形  网络字节序 -->主机字节序
    uint32_ntohl(uint32_t netlong) //长整形  网络字节序 -->主机字节序

4.ip地址转换函数

  int inet_pton(int af,const char *src,void *dst) //主机ip地址 -->网络ip字节序
    注: 主机ip地址是字符串 、网络ip字节序是整形
    (1) af : IP协议 AF_INET、AF_INET6
    (2) src: 传入参数 十进制的ip地址
    (3) dst:大整形ip 存入地址

    //网络ip字节序 --> 主机ip地址
    const char* inet_ntop(int af,const void *src,char *dst,socklen_t size)
    返回值:成功返回指向 dst的指针 失败返回空指针

与此相关只能转换AF_INET ip字节序的函数

inet_addr IP地址的字符串赋值转换为in_addr类型

inet_ntoa,可以把一个in_addr类型转换为一个字符串。

5.sockaddr和sockaddr_in

sockaddr

头文件#include <sys/socket.h>中定义

sockaddr的缺点:sa_data把目标地址和端口存在一起

struct sockaddr {  
     sa_family_t sin_family;//地址族
    char sa_data[14]; //前2字节:端口 后4字节:ip地址 后8字节作为填充        
 };

sockaddr_in

struct sockaddr_in{

short sin_family;//(地址族)

unsigned short sin_port;/*端口号*/

struct in_addr sin_addr;/*IP 地址*/

unsigned char sin_zero[8];/*Same size as struct sockaddr没有实际意义,只是为了 跟SOCKADDR结构在内存中对齐*/

};

我的理解:网络通信api的参数默认为sockaddr,但由于不好指定端口和ip地址,一般定义sockaddr_in 来方便赋值端口和ip地址,调用api函数时强转为sockaddr类型即可

6. 服务器端基本函数 bind listen accept

int bind( int sockfd , const struct sockaddr * my_addr, socklen_t addrlen);

int listen(int fd, int backlog)

int accept(int sockfd, struct sockaddr *addr, socklen_t *addrlen);

7. 客户端基本函数  connect

int connect(int sock, struct sockaddr *serv_addr, socklen_t addrlen)

8.send 和 recv 

int send( SOCKET s, const char *buf, int len, int flags );

int recv( SOCKET s, const char *buf, int len, int flags);

8.多线程

头文件 pthread.h

创建线程 pthread_create (与windows CreateThread 用法相似)

int pthread_create(pthread_t *tidp,const pthread_attr_t *attr,void *(*start_rtn)(void*),void *arg);

 pthread_detach()与pthread_join 

pthread_detach()即主线程与子线程分离,子线程结束后,资源自动回收。

pthread_join()即是子线程合入主线程,主线程阻塞等待子线程结束,然后回收子线程资源。

int pthread_join(pthread_t tid);  若成功则返回0,若出错则为非零。

int pthread_join(pthread_t tid);  若成功则返回0,若出错则为非零。

9.通信流程

10.多线程并发样例程序 

服务器端

#include<stdio.h>
#include<stdlib.h>
#include<unistd.h>
#include<string.h>
#include<arpa/inet.h>
#include<pthread.h>void * working(void *arg);struct SockInfo
{struct sockaddr_in addr;int fd;
};struct SockInfo infos[512];int main()
{//1.创建监听的套接字int fd = socket(AF_INET,SOCK_STREAM,0);if(fd==-1){perror("socket");return -1;}//2.连接本地的ip 端口struct sockaddr_in saddr;saddr.sin_family =AF_INET;saddr.sin_port = htons(9999);saddr.sin_addr.s_addr = INADDR_ANY;int ret = bind(fd,(struct sockaddr*) &saddr,sizeof(saddr));if(ret==-1){perror("bind");return -1;}//3.设置监听ret = listen(fd,128);if(ret==-1){perror("listen");return -1;}//初始化客户端数组int max = sizeof(infos)/sizeof(infos[0]);for(int i=0; i<max;i++){bzero(&infos[i],sizeof(infos[i]));infos[i].fd=-1;}//4.阻塞并等待客户端的连接while(1){struct SockInfo * pinfo;int addrlen =sizeof(sockaddr_in);for(int i=0; i<max;i++){if(infos[i].fd==-1){pinfo=&infos[i];break;}}int cfd= accept(fd,(struct sockaddr*) &pinfo->addr,&addrlen);if(cfd==-1){perror("accept");continue;}pinfo->fd=cfd;//创建子线程pthread_t tid;pthread_create(&tid,NULL,working,pinfo);phread_detach(tid);}close(fd);return 0;
}
void working(void *arg)
{//5.连接成功打印客户端信息struct SockInfo *pinfo = (struct SockInfo*) arg;char ip[32];printf("客户端ip: %s, 端口: %d\n",inet_ntop(AF_INET,&pinfo->addr.sin_addr.s_addr,ip,sizeof(ip)),ntohs(&pinfo->addr.sin_port));while(1){//接受数据char buf[1024];int len =recv(pinfo->fd,buf,sizeof(buf),0);if(len>0){printf("client say: %s",buf);send(pinfo->fd,buf,sizeof(buf),0);}else if(len==0){printf("clinet closed!\n");break;}else{perror("recv");break;}}//关闭socketclose(pinfo->fd);return NULL;
}

客户端

#include<stdio.h>
#include<stdlib.h>
#include<unistd.h>
#include<string.h>
#include<arpa/inet.h>int main()
{ //1.创建通信的套接字int fd = socket(AF_INET,SOCK_STREAM,0);if(fd==-1){perror("socket");return -1;}//2.连接服务器的ip 端口struct sockaddr_in saddr;saddr.sin_family =AF_INET;saddr.sin_port = htons(9999);inet_pton(AF_INET,"121.41.88.239",&saddr.sin_addr.s_addr);int ret = connect(fd,(struct sockaddr*) &saddr,sizeof(saddr));if(ret==-1){perror("connect");return -1;}int number=0;while(1){//接受数据char buff[1024];sprintf(buff,"hello %d\n ",number++);send(fd,buff,strlen(buff)+1,0);memset(buff,0,sizeof buff);int len=recv(fd,buff,sizeof(buff),0);if(len>0){printf("server say: %s\n",buff);}else if(len==0){printf("server closed!\n");break;}else{perror("recv");break;}sleep(1);}//关闭socketclose(fd);return 0;
}

Linux网络编程基础及多线程并发案例相关推荐

  1. Linux网络编程基础<多进程并发服务器>

    一.应用场景 最简单的socket示列代码只能一个客户端连接一个服务器,并不支持多个客户端对服务器的连接,为了能让多个客户端进行连接所以需要多进程或者多线程处理 二.思路解析 服务器端的程序是俩个套接 ...

  2. Linux网络编程基础知识

    Linux网络编程基础知识 1. 协议的概念 1.1 什么是协议 1.2 典型协议 2 网络应用程序设计模式 2.1 C/S模式 2.2 B/S模式 2.3 优缺点 3 分层模型 3.1 OSI七层模 ...

  3. Linux网络编程基础1(网络应用程序设计模式,分层模型,协议格式)

    Linux网络编程基础(网络应用程序设计模式,socket编程,inet_pton,inet_ntop,服务端创建连接的过程,客户端创建连接的过程,socket函数封装) 1. 网络应用程序设计模式 ...

  4. Linux网络编程基础和一步一步学

    ·Linux网络编程 基础(一) ·Linux网络编程 基础(二) ·Linux网络编程 基础(三) ·Linux网络编程 基础(四) ·Linux网络编程 基础(五) ·Linux网络编程 基础(六 ...

  5. Linux网络编程基础

    2019独角兽企业重金招聘Python工程师标准>>> (一)Linux网络编程--网络知识介绍 Linux网络编程--网络知识介绍 客户端和服务端 网络程序和普通的程序有一个最大的 ...

  6. Linux网络编程服务器模型选择之并发服务器(上)

    转载:http://www.cnblogs.com/lizhenghn/p/3617666.html 与循环服务器的串行处理不同,并发服务器对服务请求并发处理.循环服务器只能够一个一个的处理客户端的请 ...

  7. 【Linux网络编程部分----多进程高并发poll模型】

    目录 前言 背景 分析 编写步骤 服务器: 客户端: 服务器端代码 附:文件操作部分 附:目录操作部分 客户端代码 全部代码 头文件部分 服务器全部代码 客户端所有代码 总结: 前言 本文采用  Vi ...

  8. linux 网络编程 ping,Linux 网络编程基础(4) -- Ping 的C代码实现

    1.背景 在进行网络编程的时候,通常使用的协议有TCP协议,UDP协议.这些协议在简历套接字之初需要制定套接字的类型,比如TCP应当设置为 SOCK_STREAM, UDP对应的套接字应当设置为SOC ...

  9. Linux高性能服务器编程 第5章 Linux网络编程基础API

    5.1 socket 地址 API 现代CPU的累加器一次都能装载(至少)4 字节(这里考虑32位机,下同),即一个整 数.那么这4 字节在内存中排列的顺序将影响它被累加器装载成的整数的值.这就是字节 ...

最新文章

  1. SQL Date 函数
  2. flutter 一行代码取消 返回按钮
  3. linux 安装u盘win7系统安装教程,centos u盘安装 boot制作u盘win7盘工具
  4. 使用 Boost.Math 计算 Jacobi Zeta 函数的简单示例, 并使用相应的 WolframAlpha 命令
  5. Jupyter Noteboot 添加kernel 环境
  6. 基于springMVC拦截器实现操作日志统计
  7. CrudRepository/JpaRepository/PagingAndSortingRepository之间的区别
  8. 带你走进SAP项目实施过程——前言(0)
  9. php radiobutton,radiobutton怎么用
  10. python第七天--文件练
  11. 凌度行车记录仪刷机包_凌度行车记录仪怎样升级?
  12. 用手机玩转ContextCapture(Smart3D)跑出惊艳三维模型
  13. 2022年最新BIM计费标准,涉及14省市
  14. 租服务器的 直连100m是啥,如何知道我的服务器带宽是独享10M或者100M?
  15. 正睿OI补题(贪心)
  16. 戴尔 OptiPlex 3020重新安装win10系统的教程
  17. 如何使用电脑上的谷歌浏览器来调试安卓手机上的移动端页面
  18. NLP(八):文本表示:word2vec原理及其gensim实现
  19. 关于JS中的内存溢出与内存泄漏
  20. LeetCode 2423. Remove Letter To Equalize Frequency【哈希表】简单

热门文章

  1. 基于Tensorflow的英文评论二分类CNN模型
  2. Python3学习笔记23-StringIO和BytesIO
  3. 鸿蒙os将用在哪款机型,鸿蒙OS即将到来,首款机型现已确认,华为P50恐无缘
  4. Android Transition过渡动画
  5. 【独立版】智创云享3107、易搜资料1.4.3、变现宝1.2.4最新版
  6. 并行计算与分布式处理的区别
  7. SQLException: Value ‘0000-00-00 00:00:00‘ can not be represented as java.sql.Timestamp
  8. 【python】 安装浏览器驱动器
  9. Android自定义动画----蜘蛛网格图
  10. 2023最新帝国CMS7.5手赚网试玩平台源码/可封装APP+带文章功能系统