1. #include "hl.h"
    2. int main (void)
    3. {
    4. int fd = -1;
    5. struct sockaddr_in sin;
    6. /* 1. 创建socket fd */
    7. if ((fd = socket (AF_INET, SOCK_STREAM, 0)) < 0) {
    8. perror ("socket");
    9. exit (1);
    10. }
    11. /*2. 绑定 */
    12. /*2.1 填充struct sockaddr_in结构体变量 */
    13. bzero (&sin, sizeof (sin));
    14. sin.sin_family = AF_INET;
    15. sin.sin_port = htons (SERV_PORT); //网络字节序的端口号
    16. /*优化1: 让服务器程序能绑定在任意的IP上 */
    17. #if 1
    18. sin.sin_addr.s_addr = htonl (INADDR_ANY);
    19. #else
    20. if (inet_pton (AF_INET, SERV_IP_ADDR, (void *) &sin.sin_addr) != 1) {
    21. perror ("inet_pton");
    22. exit (1);
    23. }
    24. #endif
    25. /*2.2 绑定 */
    26. if (bind (fd, (struct sockaddr *) &sin, sizeof (sin)) < 0) {
    27. perror ("bind");
    28. exit (1);
    29. }
    30. /*3. 调用listen()把主动套接字变成被动套接字 */
    31. if (listen (fd, BACKLOG) < 0) {
    32. perror ("listen");
    33. exit (1);
    34. }
    35. printf ("Server starting....OK!\n");
    36. int newfd = -1;
    37. /*4. 阻塞等待客户端连接请求 */
    38. #if 0
    39. newfd = accept (fd, NULL, NULL);
    40. if (newfd < 0) {
    41. perror ("accept");
    42. exit (1);
    43. }
    44. #else
    45. /*优化2:通过程序获取刚建立连接的socket的客户端的IP地址和端口号 */
    46. struct sockaddr_in cin;
    47. socklen_t addrlen = sizeof (cin);
    48. if ((newfd = accept (fd, (struct sockaddr *) &cin, &addrlen)) < 0) {
    49. perror ("accept");
    50. exit (1);
    51. }
    52. char ipv4_addr[16];
    53. if (!inet_ntop (AF_INET, (void *) &cin.sin_addr, ipv4_addr, sizeof (cin))) {
    54. perror ("inet_ntop");
    55. exit (1);
    56. }
    57. printf ("Clinet(%s:%d) is connected!\n", ipv4_addr, htons (cin.sin_port));
    58. #endif
    59. /*5. 读写 */
    60. //..和newfd进行数据读写
    61. int ret = -1;
    62. char buf[BUFSIZ];
    63. while (1) {
    64. bzero (buf, BUFSIZ);
    65. do {
    66. ret = read (newfd, buf, BUFSIZ - 1);
    67. } while (ret < 0 && EINTR == errno);
    68. if (ret < 0) {
    69. perror ("read");
    70. exit (1);
    71. }
    72. if (!ret) { //对方已经关闭
    73. break;
    74. }
    75. printf ("Receive data: %s\n", buf);
    76. if (!strncasecmp (buf, QUIT_STR, strlen (QUIT_STR))) { //用户输入了quit字符
    77. printf ("Client is exiting!\n");
    78. break;
    79. }
    80. }
    81. close (newfd);
    82. close (fd);
    83. return 0;
    84. }