栏目分类:
子分类:
返回
名师互学网用户登录
快速导航关闭
当前搜索
当前分类
子分类
实用工具
热门搜索
名师互学网 > IT > 软件开发 > 后端开发 > C/C++/C#

c++每日八股文---socket实现简单的TCP通信

C/C++/C# 更新时间: 发布时间: IT归档 最新发布 模块sitemap 名妆网 法律咨询 聚返吧 英语巴士网 伯小乐 网商动力

c++每日八股文---socket实现简单的TCP通信

一 、流程

二、网络字节序

uint32_t htonl(uint32_t hostlong)    //本地字节序转网络字节序(IP)
uint16_t htons(unit16_t hsoshort)    //本地字节序转网络字节序(端口)
uint32_t ntohl(unit32_t netlong)    //网络字节序转本地字节序(端口)
uint16_t ntohs(unit16_t netshort)    //网络字节序转本地字节序(端口)

IP地址转换函数(常用的)

int inet_pton(int af, const char *src, void *dst)

把点分十进制的ip转换为网络字节序
af:当前的ip协议类型AF_INET AF_INET6
src:传入参数 IP地址(点分十进制)
dst:传出参数 转换后的网络字节序的IP地址
成功返回1 异常返回0(src指向的不是有效的IP地址) 失败返回-1

 const char *inet_ntop(int af, const void *src,
                             char *dst, socklen_t size)

把网络字节序转换为本地字节序
af:AF_INET AF_INET6
src: 传入参数 网络字节序IP地址
dst:传出参数 本地字节序(string IP)
size:字节序的大小

三、函数API
1、

struct sockaddr 
struct sockaddr_in {
               sa_family_t    sin_family; 
               in_port_t      sin_port;   
               struct in_addr sin_addr;   
           };
           
           struct in_addr {
               uint32_t       s_addr;     
           };

初始化的时候用下面的结构体初始化,传参的时候在强转为上面结构体的指针
成员初始化:
sin_family :AF_INET/AF_INET6(ipv4/ipv6)
sin_port:网络字节序的端口号
sin_addr.s_addr:(结构体嵌套结构体)网络字节序的IP地址 一般情况下赋值方法为

serv_addr.sin_addr.s_addr = htonl(INADDR_ANY);

自动取当前系统中有效的IP地址。 默认整形,进行字节序转换

2、

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

socket函数:创建一个套接字
domain:选用的IP地址协议 通常为AF_INET(IPV4)、AF_INET6(IPV6)。
type:创建套接字所选用的数据传输协议 SOCK_STREAM、SOCK_DGRAM
protocol:所选用的协议的代表协议,默认为0(根据前面的所选的类型自动确定)(TCP/UDP)
返回值:成功:新套接字所对应的文件描述符 。失败:返回-1。
3、

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

bind:给socket绑定地址结构(IP + 端口号)
sockfd:socket函数的返回值
addr:传入参数(struct sockaddr *)&addr (进行强转)
addrlen:sizeof(addr)地址结构的大小
返回值:成功:0 。 失败-1。
4、

int listen(int sockfd, int backlog)

listen:设置同时与服务器链接的上限数(同时进行三次握手的客户端数量)
sockfd:socket函数的返回值
backlog:同时连接的数值
5、

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

accept:阻塞等待客户端连接,成功返回一个与客户端链接的socket文件描述符(新的文件描述符)
sockfd:socked函数的返回值。
addr:传出参数。成功与服务器建立链接的客户端的地址结构(IP+PORT)。
addrlen:传入传出参数。入:addr的大小 。 出:客户端addr的实际大小。

clit_addr_len = sizeof(clit_addr);

传参的时候传&clit_addr_len。
返回值:返回能与服务器进行数据通信的socket对应的文件描述符。失败返回-1。
6、

int connect(int sockfd, const struct sockaddr *addr,
                   socklen_t addrlen)

connect:与服务器建立连接
sockfd:客户端scoket函数的返回值
addr:传入参数 服务器的地址结构
addrlen:服务器地址结构的大小。
返回值: 成功0 失败-1。

三、代码实现
实现功能:客户端输入小写字符,服务器将小写字母转换为大写字母返回给客户端并打印。
服务器端:

  1 #include
  2 #include
  3 #include
  4 #include
  5 #include
  6 #include
  7 #include
  8 
  9 #define SERV_PORT  9257
 10 
 11 int main()
 12 {
 13     int lfd = 0;
 14     int cfd = 0;
 15     char buf[BUFSIZ], client_IP[1024];
 16     //定义结构体并初始化
 17     struct sockaddr_in serv_addr, clit_addr;
 18     socklen_t clit_addr_len;
 19     serv_addr.sin_family = AF_INET;
 20     serv_addr.sin_port = htons(SERV_PORT);
 21     serv_addr.sin_addr.s_addr = htonl(INADDR_ANY);
 22 
 23     //创建socket
 24     lfd = socket(AF_INET, SOCK_STREAM, 0);
 25     if (lfd == -1){
 26         perror("socket error");
 27         exit(1);
 28     }
 29 
 30     //绑定
 31     int ret = bind(lfd, (const struct sockaddr *)&serv_addr, sizeof(serv_addr));
 32     if (ret == -1){
 33         perror("bid error");
 34         exit(1);
 35     }
 36 
 37     ret = listen(lfd, 128);
 38     if (ret == -1){
 39         perror("listen error");
 40         exit(1);
 41     }
 42 
 43     //阻塞监听客户端建立链接 返回新的文件描述符
 44     clit_addr_len = sizeof(clit_addr);
 45     cfd = accept(lfd, (struct sockaddr *)&clit_addr, &clit_addr_len);
 46     if (cfd == -1){
 47         perror("accept error");
 48         exit(1);
 49     }
 50     printf("client ip:%s port:%dn",
 51             inet_ntop(AF_INET, &clit_addr.sin_addr.s_addr, client_IP, sizeof(client_IP)),
 52             ntohs(clit_addr.sin_port));
 53 
 54     //服务器工作:读文件
 55     int i = 0;
 56     while(1){
 57         ret = read(cfd, buf, sizeof(buf));
 58         write(STDOUT_FILENO, buf, ret);
 59         for(i = 0; i < ret; i ++){
 60             buf[i] = toupper(buf[i]); //小写转大写
 61         }
 62         write(cfd, buf, ret);
 63     }
 64 
 65     close(cfd);
 66     close(lfd);
 67     return 0;
 68 }

客户端:

  1 #include
  2 #include
  3 #include
  4 #include
  5 #include
  6 #include
  7 
  8 #define SERV_PORT 9257
  9 
 10 int main()
 11 {
 12     int cfd;
 13     int conter = 10;
 14     char buf[BUFSIZ];
 15 
 16     struct sockaddr_in  serv_addr; //服务器的地址结构
 17     serv_addr.sin_family = AF_INET;
 18     serv_addr.sin_port = htons(SERV_PORT);
 19     inet_pton(AF_INET, "127.0.0.1", &serv_addr.sin_addr);
 20     serv_addr.sin_addr.s_addr = htonl(INADDR_ANY);
 21 
 22     cfd = socket(AF_INET, SOCK_STREAM, 0);
 23     if (cfd == -1){
 24         perror("socket error");
 25         exit(1);
 26     }
 27 
 28     int ret = connect(cfd, (const struct sockaddr *)&serv_addr, sizeof(serv_addr));
 29     if (ret != 0){
 30         perror("connect error");
 31         exit(1);
 32     }
 33     while(conter--){
 34         write(cfd, "hellon", 6);
 35         ret = read(cfd, buf, sizeof(buf));
 36         write(STDOUT_FILENO, buf, ret);
 37         sleep(1);
 38     }
 39     close(cfd);
 40     return 0;
 41 }
 42 

程序运行结果:

转载请注明:文章转载自 www.mshxw.com
本文地址:https://www.mshxw.com/it/849213.html
我们一直用心在做
关于我们 文章归档 网站地图 联系我们

版权所有 (c)2021-2022 MSHXW.COM

ICP备案号:晋ICP备2021003244-6号