기술나눔

네트워크 프로그래밍 학습을 위한 UDP

2024-07-12

한어Русский языкEnglishFrançaisIndonesianSanskrit日本語DeutschPortuguêsΕλληνικάespañolItalianoSuomalainenLatina

UDP 프로그래밍 프로세스

센토는 차단하지 않습니다

채팅방 효과 실현

온라인

채팅

오프라인

서버에는 이름과 IP 주소를 유지하기 위한 주소가 필요합니다.

상호 작용 중 구조 보내기

다음 매크로는 C 언어에서만 사용할 수 있습니다.

ser.sin_port = htons(50000);

위의 포트 번호는 50000 이상이며 양쪽이 동일해야 합니다.

UDP가 너무 빨리 전송하도록 하지 말고, 뭔가를 저쪽으로 보내세요.

보내는 횟수와 받는 횟수가 동일해야 합니다.

무국적

왜 비교종료기호 안에 오른쪽이 적혀있나요?

UDP로 송수신되는 데이터에 경계가 있는지 확인

Netstat는 네트워크 상태를 볼 수 있습니다

서비스 터미널

  1. #include <stdio.h>
  2. #include <stdlib.h>
  3. #include <unistd.h>
  4. #include <string.h>
  5. #include <sys/types.h> /* See NOTES */
  6. #include <sys/socket.h>
  7. #include <netinet/in.h>
  8. #include <netinet/ip.h>
  9. #include <arpa/inet.h>
  10. #include <time.h>
  11. typedef struct sockaddr * (SA);
  12. typedef enum {CMD_LOGIN,CMD_CHAT,CMD_LOGOUT}TYPE;
  13. typedef struct
  14. {
  15. TYPE type;
  16. char name[50];
  17. char context[128];
  18. }MSG;
  19. typedef struct
  20. {
  21. struct sockaddr_in cli;
  22. int flag; // 0 free 1 occu
  23. }LIST;
  24. #define MAX 10
  25. LIST list[MAX]={0};
  26. int do_login(int sockfd,MSG* msg,struct sockaddr_in* cli)
  27. {
  28. int i = 0 ;
  29. for(i=0;i<MAX;i++)
  30. {
  31. if(1 == list[i].flag )
  32. {
  33. sendto(sockfd,msg,sizeof(MSG),0,(SA)&list[i].cli,sizeof(list[i].cli));
  34. }
  35. }
  36. for(i=0;i<MAX;i++)
  37. {
  38. if(0 == list[i].flag )
  39. {
  40. list[i].flag =1;
  41. //list[i].cli = *cli;
  42. memcpy(&list[i].cli,cli,sizeof(*cli));
  43. break;
  44. }
  45. }
  46. return 0;
  47. }
  48. int do_chat(int sockfd, MSG* msg,struct sockaddr_in*cli)
  49. {
  50. int i = 0 ;
  51. for(i=0;i<MAX;i++)
  52. {
  53. if(1 == list[i].flag && 0!=memcmp(&list[i].cli,cli,sizeof(*cli)) )
  54. {
  55. sendto(sockfd,msg,sizeof(MSG),0,(SA)&list[i].cli,sizeof(list[i].cli));
  56. }
  57. }
  58. }
  59. int do_logout(int sockfd, MSG* msg,struct sockaddr_in*cli)
  60. {
  61. return 0;
  62. }
  63. int main(int argc, char *argv[])
  64. {
  65. int sockfd = socket(AF_INET,SOCK_DGRAM,0);
  66. if(-1 == sockfd)
  67. {
  68. perror("socket");
  69. exit(1);
  70. }
  71. // man 7 ip
  72. struct sockaddr_in ser,cli;
  73. bzero(&ser,sizeof(ser));
  74. bzero(&cli,sizeof(cli));
  75. ser.sin_family = AF_INET;
  76. // 大小端转化 host to net short
  77. ser.sin_port = htons(50000);
  78. ser.sin_addr.s_addr = inet_addr("127.0.0.1");
  79. int ret = bind(sockfd,(SA)&ser,sizeof(ser));
  80. if(-1 == ret)
  81. {
  82. perror("bind");
  83. exit(1);
  84. }
  85. socklen_t len = sizeof(cli);
  86. MSG msg;
  87. while(1)
  88. {
  89. bzero(&msg,sizeof(msg));
  90. recvfrom(sockfd,&msg,sizeof(msg),0,(SA)&cli,&len);
  91. switch(msg.type)
  92. {
  93. case CMD_LOGIN:
  94. do_login(sockfd,&msg,&cli);
  95. break;
  96. case CMD_LOGOUT:
  97. do_logout(sockfd,&msg,&cli);
  98. break;
  99. case CMD_CHAT:
  100. do_chat(sockfd,&msg,&cli);
  101. break;
  102. }
  103. }
  104. close(sockfd);
  105. return 0;
  106. }

사용자 터미널

  1. #include <stdio.h>
  2. #include <stdlib.h>
  3. #include <unistd.h>
  4. #include <string.h>
  5. #include <sys/types.h> /* See NOTES */
  6. #include <sys/socket.h>
  7. #include <netinet/in.h>
  8. #include <netinet/ip.h>
  9. #include <arpa/inet.h>
  10. #include <time.h>
  11. typedef struct sockaddr * (SA);
  12. typedef enum {CMD_LOGIN,CMD_CHAT,CMD_LOGOUT}TYPE;
  13. typedef struct
  14. {
  15. TYPE type;
  16. char name[50];
  17. char context[128];
  18. }MSG;
  19. int main(int argc, char *argv[])
  20. {
  21. int sockfd = socket(AF_INET,SOCK_DGRAM,0);
  22. if(-1 == sockfd)
  23. {
  24. perror("socket");
  25. exit(1);
  26. }
  27. // man 7 ip
  28. struct sockaddr_in ser,cli;
  29. bzero(&ser,sizeof(ser));
  30. ser.sin_family = AF_INET;
  31. // 大小端转化 host to net short
  32. ser.sin_port = htons(50000);
  33. ser.sin_addr.s_addr = inet_addr("127.0.0.1");
  34. socklen_t len = sizeof(cli);
  35. MSG msg;
  36. char name[50]={0};
  37. printf("input name:");
  38. fgets(name,sizeof(name),stdin);
  39. name[strlen(name)-1]='0';
  40. msg.type = CMD_LOGIN;
  41. strcpy(msg.name ,name);
  42. strcpy(msg.context,"login");
  43. sendto(sockfd,&msg,sizeof(msg),0,(SA)&ser,sizeof(ser));
  44. pid_t pid = fork();
  45. if(pid>0)
  46. {
  47. while(1)
  48. {
  49. bzero(&msg,sizeof(msg));
  50. recvfrom(sockfd,&msg,sizeof(msg),0,NULL,NULL);
  51. printf("%s:%sn",msg.name,msg.context);
  52. }
  53. }
  54. else if(0==pid)
  55. {
  56. while(1)
  57. {
  58. printf("to all");
  59. char buf[128]={0};
  60. strcpy(msg.name,name);
  61. msg.type = CMD_CHAT;
  62. fgets(msg.context,sizeof(msg.context),stdin);//#quit
  63. msg.context[strlen(msg.context)-1]='0';
  64. if(0==strcmp(msg.context,"#quit"))
  65. {
  66. msg.type = CMD_LOGOUT;
  67. strcpy(msg.context,"CMD_LOGOUT");
  68. }
  69. sendto(sockfd,&msg,sizeof(msg),0,(SA)&ser,sizeof(ser));
  70. }
  71. }
  72. else
  73. {
  74. perror("fork");
  75. exit(1);
  76. }
  77. close(sockfd);
  78. return 0;
  79. }