• 2024/4/16 网络编程day4


    1. /*TCP并发服务器端*/
    2. #include <myhead.h>
    3. #define SER_IP "192.168.125.173"
    4. #define SER_PORT 8888
    5. void sighanger(int signum){
    6. if(signum==SIGCHLD){//子进程终止信号
    7. while(waitpid(-1,NULL,WNOHANG)>0);//循环回收僵尸进程
    8. }
    9. }
    10. int main(int argc, const char *argv[])
    11. {
    12. //函数调用出错返回SIG_ERR
    13. if(signal(SIGCHLD,sighanger)==SIG_ERR){
    14. perror("signal error");
    15. return -1;
    16. }
    17. //创建套接字
    18. int rfd=socket(AF_INET,SOCK_STREAM,0);
    19. if(rfd==-1){
    20. perror("socket error");
    21. return -1;
    22. }
    23. printf("socket success\n");
    24. //为服务器绑定ip地址端口号
    25. struct sockaddr_in cin;
    26. cin.sin_family=AF_INET;
    27. cin.sin_port=htons(SER_PORT);
    28. cin.sin_addr.s_addr=inet_addr(SER_IP);
    29. if(bind(rfd,(struct sockaddr*)&cin,sizeof(cin))==-1){
    30. perror("bind error");
    31. return -1;
    32. }
    33. //设置监听
    34. if(listen(rfd,128)==-1){
    35. perror("listen error");
    36. return -1;
    37. }
    38. printf("listen success\n");
    39. struct sockaddr_in sin;
    40. socklen_t socklen=sizeof(sin);
    41. while(1){//循环接收客户端请求
    42. int newfd=accept(rfd,(struct sockaddr*)&sin,&socklen);
    43. if(newfd==-1){
    44. perror("accept error");
    45. return -1;
    46. }
    47. pid_t pid=fork();
    48. if(pid>0){
    49. close(newfd);
    50. }else if(pid==0){//子进程数据通信
    51. close(rfd);
    52. char rbuf[128]="";
    53. while(1){
    54. bzero(rbuf,sizeof(rbuf));
    55. int res=read(newfd,rbuf,sizeof(rbuf));
    56. if(res==0){
    57. printf("客户端已下线\n");
    58. break;
    59. }
    60. printf("[%s:%d]:%s\n",inet_ntoa(cin.sin_addr),ntohs(cin.sin_port),rbuf);
    61. //将字符串加777发送回去
    62. strcat(rbuf,"777");
    63. write(newfd,rbuf,sizeof(rbuf));
    64. printf("发送成功\n");
    65. }
    66. close(newfd);
    67. exit(EXIT_SUCCESS);
    68. }
    69. }
    70. close(rfd);
    71. return 0;
    72. }

    1. //多线程实现TCP并发服务器
    2. #include<myhead.h>
    3. #define SER_IP "192.168.125.117" //服务器IP地址
    4. #define SER_PORT 8888 //服务器端口号
    5. //定义用于给线程体传参的结构体类型
    6. struct MsgInfo
    7. {
    8. int newfd;
    9. struct sockaddr_in cin;
    10. };
    11. //定义线程体函数
    12. void *deal_cli_msg(void *arg)
    13. {
    14. //将传递进来的数据解析出来
    15. int newfd = ((struct MsgInfo*)arg)->newfd;
    16. struct sockaddr_in cin = ((struct MsgInfo*)arg)->cin;
    17. //5、数据通信
    18. char rbuf[128] = ""; //用于接受消息
    19. while(1)
    20. {
    21. bzero(rbuf, sizeof(rbuf)); //清空容器
    22. //从套接字文件中读取消息
    23. //int ret = read(newfd, rbuf, sizeof(rbuf));
    24. int ret = recv(newfd, rbuf, sizeof(rbuf), 0);
    25. if(ret == 0)
    26. {
    27. printf("客户端已下线\n");
    28. break;
    29. }
    30. printf("[%s:%d]: %s\n", \
    31. inet_ntoa(cin.sin_addr), ntohs(cin.sin_port),rbuf );
    32. //将字符串加个笑脸回回去
    33. strcat(rbuf, "*_*");
    34. //write(newfd, rbuf, strlen(rbuf));
    35. send(newfd, rbuf, strlen(rbuf), 0);
    36. printf("发送成功\n");
    37. }
    38. //6、关闭套接字
    39. close(newfd);
    40. //退出线程
    41. pthread_exit(NULL);
    42. }
    43. /**主程序**/
    44. int main(int argc, const char *argv[])
    45. {
    46. //1、创建套节字:用于接收客户端链接请求的
    47. int sfd = socket(AF_INET, SOCK_STREAM, 0);
    48. if(sfd == -1)
    49. {
    50. perror("socket error");
    51. return -1;
    52. }
    53. printf("socket success sfd = %d\n", sfd); //3
    54. //设置端口号快速重用
    55. int reuse = 1;
    56. if(setsockopt(sfd, SOL_SOCKET, SO_REUSEADDR, &reuse, sizeof(reuse))==-1)
    57. {
    58. perror("setsockopt error");
    59. return -1;
    60. }
    61. printf("端口号快速重用成功\n");
    62. //2、绑定IP地址和端口号
    63. //2.1 填充地址信息结构体
    64. struct sockaddr_in sin;
    65. sin.sin_family = AF_INET; //地址族
    66. sin.sin_port = htons(SER_PORT); //端口号
    67. sin.sin_addr.s_addr = inet_addr(SER_IP); //IP地址
    68. //2.2 绑定工作
    69. if( bind(sfd, (struct sockaddr*)&sin, sizeof(sin)) ==-1)
    70. {
    71. perror("bind error");
    72. return -1;
    73. }
    74. printf("bind success\n");
    75. //3、讲套节字设置成被动监听状态
    76. if( listen(sfd, 128) == -1)
    77. {
    78. perror("listen error");
    79. return -1;
    80. }
    81. printf("listen success\n");
    82. //4、阻塞等待客户端连接请求
    83. //定义地址信息结构体变量用于接受客户端的地址信息
    84. struct sockaddr_in cin;
    85. socklen_t socklen = sizeof(cin); //接受地址信息的长度
    86. while(1)
    87. {
    88. int newfd = accept(sfd, (struct sockaddr*)&cin, &socklen);
    89. if(newfd == -1)
    90. {
    91. perror("accept error");
    92. return -1;
    93. }
    94. printf("[%s:%d]:已连接, newfd = %d\n",\
    95. inet_ntoa(cin.sin_addr), ntohs(cin.sin_port) ,newfd); //4
    96. //定义用于传参的变量
    97. struct MsgInfo info = {newfd, cin};
    98. //创建分支线程用于通信
    99. pthread_t tid = -1;
    100. if(pthread_create(&tid, NULL, deal_cli_msg, &info) != 0)
    101. {
    102. printf("线程创建失败\n");
    103. return -1;
    104. }
    105. //回收分支线程的资源
    106. pthread_detach(tid);
    107. }
    108. close(sfd);
    109. return 0;
    110. }

    1. //流式域套接字服务器端
    2. #include<myhead.h>
    3. int main(int argc, const char *argv[])
    4. {
    5. //1、创建套节字:用于接收客户端链接请求的
    6. int sfd = socket(AF_UNIX, SOCK_STREAM, 0);
    7. if(sfd == -1)
    8. {
    9. perror("socket error");
    10. return -1;
    11. }
    12. printf("socket success sfd = %d\n", sfd); //3
    13. //判断要绑定的套接字文件是否存在,如果存在,需要将其删除
    14. if(access("./unix", F_OK) == 0)
    15. {
    16. //说明文件存在,需要将其删除
    17. if(unlink("./unix") != 0)
    18. {
    19. perror("unlink error");
    20. return -1;
    21. }
    22. }
    23. //2、绑定套接字文件
    24. //2.1 填充地址信息结构体
    25. struct sockaddr_un sun;
    26. sun.sun_family = AF_UNIX; //通信域
    27. strcpy(sun.sun_path , "./unix"); //套接字文件
    28. //2.2 绑定工作
    29. if( bind(sfd, (struct sockaddr*)&sun, sizeof(sun)) ==-1)
    30. {
    31. perror("bind error");
    32. return -1;
    33. }
    34. printf("bind success\n");
    35. //3、讲套节字设置成被动监听状态
    36. if( listen(sfd, 128) == -1)
    37. {
    38. perror("listen error");
    39. return -1;
    40. }
    41. printf("listen success\n");
    42. //4、阻塞等待客户端连接请求
    43. //定义地址信息结构体变量用于接受客户端的地址信息
    44. struct sockaddr_un cun;
    45. socklen_t socklen = sizeof(cun); //接受地址信息的长度
    46. int newfd = accept(sfd, (struct sockaddr*)&cun, &socklen);
    47. if(newfd == -1)
    48. {
    49. perror("accept error");
    50. return -1;
    51. }
    52. printf("[%s]:已连接, newfd = %d\n", cun.sun_path,newfd); //4
    53. //5、数据通信
    54. char rbuf[128] = ""; //用于接受消息
    55. while(1)
    56. {
    57. bzero(rbuf, sizeof(rbuf)); //清空容器
    58. //从套接字文件中读取消息
    59. //int ret = read(newfd, rbuf, sizeof(rbuf));
    60. int ret = recv(newfd, rbuf, sizeof(rbuf), 0);
    61. if(ret == 0)
    62. {
    63. printf("客户端已下线\n");
    64. break;
    65. }
    66. printf("[%s]: %s\n", cun.sun_path ,rbuf );
    67. //将字符串加个笑脸回回去
    68. strcat(rbuf, "*_*");
    69. //write(newfd, rbuf, strlen(rbuf));
    70. send(newfd, rbuf, strlen(rbuf), 0);
    71. printf("发送成功\n");
    72. }
    73. //6、关闭套接字
    74. close(newfd);
    75. close(sfd);
    76. return 0;
    77. }

    1. //报式域套接字服务器端
    2. #include<myhead.h>
    3. int main(int argc, const char *argv[])
    4. {
    5. //1、创建用于通信的套接字文件描述符
    6. int sfd = socket(AF_UNIX, SOCK_DGRAM, 0);
    7. if(sfd == -1)
    8. {
    9. perror("socket error");
    10. return -1;
    11. }
    12. printf("socket success sfd = %d\n", sfd); //3
    13. //判断要绑定的套接字文件是否存在,如果存在,需要将其删除
    14. if(access("./unix", F_OK) == 0)
    15. {
    16. //说明文件存在,需要将其删除
    17. if(unlink("./unix") != 0)
    18. {
    19. perror("unlink error");
    20. return -1;
    21. }
    22. }
    23. //2、绑定IP地址和端口号
    24. //2.1 填充地址信息结构体
    25. struct sockaddr_un sun;
    26. sun.sun_family = AF_UNIX; //协议族
    27. strcpy(sun.sun_path, "./unix"); //服务器的套接字文件
    28. //2.2 绑定工作
    29. if(bind(sfd, (struct sockaddr*)&sun, sizeof(sun)) == -1)
    30. {
    31. perror("bind error");
    32. return -1;
    33. }
    34. printf("bind success\n");
    35. //3、数据的收发
    36. //定义变量接收客户端地址信息结构体
    37. struct sockaddr_un cun;
    38. socklen_t socklen = sizeof(cun);
    39. char rbuf[128] = "";
    40. while(1)
    41. {
    42. bzero(rbuf, sizeof(rbuf));
    43. //读取套接字中的数据
    44. recvfrom(sfd, rbuf, sizeof(rbuf), 0, (struct sockaddr*)&cun, &socklen);
    45. printf("[%s]:%s\n",cun.sun_path, rbuf);
    46. //加个笑脸将消息回回去
    47. strcat(rbuf, "*_*");
    48. if(sendto(sfd, rbuf, strlen(rbuf), 0, (struct sockaddr*)&cun, sizeof(cun)) ==-1)
    49. {
    50. perror("write error");
    51. return -1;
    52. }
    53. printf("发送成功\n");
    54. }
    55. //4、关闭套接字
    56. close(sfd);
    57. return 0;
    58. }

    通过TFTP用UDP实现上传和下载文件

    1. #include
    2. #define SER_IP "192.168.125.99"
    3. #define SER_PORT 69
    4. #define IP "192.168.125.173"
    5. #define PORT 8888
    6. void download(char data[],short* p1,char* p2){
    7. char filename[128]="";
    8. printf("请输入要下载的文件名:");
    9. fgets(filename,sizeof(filename),stdin);
    10. filename[strlen(filename)-1]=0;
    11. int fp=open(filename,O_WRONLY | O_CREAT|O_TRUNC, 0664);//创建文件
    12. if(fp==-1){
    13. perror("open error");
    14. return ;
    15. }
    16. *p1=htons(1);//下载
    17. strcpy(p2,filename);
    18. char* p4=p2+strlen(filename)+1;
    19. strcpy(p4,"octet");
    20. int len=4+strlen(filename)+strlen("octet");
    21. printf("%s\n",p2);
    22. int sfd=socket(AF_INET,SOCK_DGRAM,0);
    23. if(sfd==-1){
    24. perror("socket error");
    25. return ;
    26. }
    27. struct sockaddr_in rin;
    28. rin.sin_family=AF_INET;
    29. rin.sin_port=htons(PORT);
    30. rin.sin_addr.s_addr=inet_addr(IP);
    31. if(bind(sfd,(struct sockaddr*)&rin,sizeof(rin))==-1){
    32. perror("bind error");
    33. return ;
    34. }
    35. printf("bind success\n");
    36. struct sockaddr_in sin;
    37. sin.sin_family=AF_INET;
    38. sin.sin_port=htons(SER_PORT);
    39. sin.sin_addr.s_addr=inet_addr(SER_IP);
    40. socklen_t sin_size = sizeof(sin);
    41. //发送下载请求
    42. sendto(sfd,data,len,0,(struct sockaddr*)&sin,sizeof(sin));
    43. char buf[516];
    44. short ack[2];
    45. ack[0]=htons(4);
    46. int res;
    47. while(1){
    48. bzero(buf,sizeof(buf));
    49. //接收数据到buf
    50. res=recvfrom(sfd, buf, sizeof(buf), 0, (struct sockaddr*)&sin, &sin_size);
    51. //返回接收数据字节数
    52. //从返回数据包中取出块编号,放到ack中去
    53. ack[1]=*(short*)(buf+2);
    54. //返回ACK确认
    55. sendto(sfd, ack, sizeof(ack), 0, (struct sockaddr*)&sin, sin_size);
    56. //将buf中的数据写到文件
    57. write(fp,buf+4,res-4);//写res-4个数据从buf+4位置到文件
    58. if(res!=516){
    59. break;
    60. }
    61. }
    62. close(fp);
    63. }
    64. void transmit(char data[],short* p1,char* p2){
    65. char filename[128]="";
    66. printf("请输入要上传的文件名:");
    67. fgets(filename,sizeof(filename),stdin);
    68. filename[strlen(filename)-1]=0;
    69. *p1=htons(2);//写,上传请求
    70. int fp=open(filename,O_RDONLY, 0664);//打开文件
    71. strcpy(p2,filename);
    72. char* p4=p2+strlen(filename)+1;
    73. strcpy(p4,"octet");
    74. int len=4+strlen(filename)+strlen("octet");
    75. int sfd=socket(AF_INET,SOCK_DGRAM,0);
    76. if(sfd==-1){
    77. perror("socket error");
    78. return ;
    79. }
    80. struct sockaddr_in rin;
    81. rin.sin_family=AF_INET;
    82. rin.sin_port=htons(PORT);
    83. rin.sin_addr.s_addr=inet_addr(IP);
    84. if(bind(sfd,(struct sockaddr*)&rin,sizeof(rin))==-1){
    85. perror("bind error");
    86. return ;
    87. }
    88. printf("bind success\n");
    89. struct sockaddr_in sin;
    90. sin.sin_family=AF_INET;
    91. sin.sin_port=htons(SER_PORT);
    92. sin.sin_addr.s_addr=inet_addr(SER_IP);
    93. socklen_t sin_size = sizeof(sin);
    94. //发送下载请求
    95. sendto(sfd,data,len,0,(struct sockaddr*)&sin,sizeof(sin));
    96. int count=1;
    97. *p1=htons(3);
    98. short* p10=data+2;
    99. while(1){
    100. *p10=htons(count);
    101. int ress=read(fp,data+4,512);
    102. if(ress==0){break;}
    103. sendto(sfd, data, sizeof(data), 0, (struct sockaddr*)&sin, sin_size);
    104. count++;
    105. }
    106. close(fp);
    107. }
    108. int main(int argc, const char *argv[])
    109. {
    110. printf("1.下载2.上传");
    111. printf("请输入>>>");
    112. int flag=0;
    113. scanf("%d",&flag);
    114. while(getchar()!=10);
    115. char data[516]="";
    116. short* p1=data;
    117. char* p2=data+2;
    118. if(flag==1){
    119. download(data,p1,p2);
    120. }else if(flag==2){
    121. transmit(data,p1,p2);
    122. }
    123. return 0;
    124. }

  • 相关阅读:
    Django与Ajax
    【路径规划-TSP问题】基于遗传算法求解多起点多TSP问题附matlab代码
    达拉斯市(Dallas)利用 OpenText 安全解决方案加速信息发现
    Vue3 企业级优雅实战 - 组件库框架 - 6 搭建example环境
    Go编译原理系列8(变量捕获)
    “CarrotMovement“ app Tech Support(URL)
    STM32F407ZGT6移植HC-05蓝牙模块
    皕杰报表之控件元素
    队列的实现和OJ练习(c语言)
    【Gazebo入门教程】第一讲 Gazebo的安装、UI界面、SDF文件介绍
  • 原文地址:https://blog.csdn.net/m0_67764503/article/details/137836133