fork download
  1. /* minitalk サーバプログラム */
  2. #include <stdio.h>
  3. #include <stdlib.h>
  4. #include <sys/types.h>
  5. #include <sys/socket.h>
  6. #include <netdb.h>
  7. #include <netinet/in.h>
  8.  
  9.  
  10. int CanIRecv(int fd){
  11. fd_set fdset;
  12. struct timeval timeout;
  13. FD_ZERO( &fdset );
  14. FD_SET( fd , &fdset );
  15. timeout.tv_sec = 0;
  16. timeout.tv_usec = 0;
  17. return select( fd+1 , &fdset , NULL , NULL , &timeout );
  18. }
  19.  
  20.  
  21. int main(int argc, char *argv[])
  22. {
  23. int srv_sock, *sock, port, m, i, j, size;
  24. struct sockaddr_in srv_addr, cli_addr;
  25. int addrlen, sendlen, recvlen;
  26. char buf[256];
  27. m = 0;
  28. size = 0;
  29. /* ポート番号を引数から取得 */
  30. port = strtol(argv[1], NULL, 10);
  31.  
  32. /* ソケットの作成 */
  33. srv_sock = socket(AF_INET, SOCK_STREAM, 0);
  34. if (srv_sock < 0) {
  35. perror("cannot create socket");
  36. exit(-1);
  37. }
  38.  
  39. /* サーバとしてバインド */
  40. srv_addr.sin_family = AF_INET;
  41. srv_addr.sin_port = htons(port);
  42. srv_addr.sin_addr.s_addr = INADDR_ANY;
  43. if (bind(srv_sock, (struct sockaddr*)&srv_addr, sizeof(srv_addr)) < 0) {
  44. perror("bind failed");
  45. exit(-1);
  46. }
  47.  
  48. /* 待ち受け人数を1人に設定 */
  49. listen(srv_sock, 1);
  50.  
  51. /* 実際の通信 */
  52. while (feof(stdin) == 0) {
  53.  
  54. if(CanIRecv(srv_sock)){
  55. /* クライアントからの接続を受け付ける */
  56. addrlen = sizeof(cli_addr);
  57. sock = (int *)realloc(sock, (size + 1) * sizeof(int) * (m + 1));
  58.  
  59. sock[m] = accept(srv_sock, (struct sockaddr*)&cli_addr, &addrlen);
  60. if (sock[m] == -1) {
  61. perror("accept failed");
  62. exit(-1);
  63. }
  64. printf("connected\n");
  65. m++;
  66. }
  67.  
  68. if(CanIRecv(0)){
  69. /* 標準入力からキーボード入力された文字を読み込む */
  70. printf("message : ");
  71. fgets(buf, sizeof(buf), stdin);
  72. for(i = 0; i <= m; i++){
  73. /* 読み込んだ文字をソケットに書き込む */
  74. sendlen = write(sock[m], buf, strlen(buf) + 1);
  75. if (sendlen < 0) {
  76. perror("cannot send a message");
  77. }
  78. }
  79. }
  80.  
  81. if (CanIRecv(sock[m])) {
  82. /* ソケットからのデータを読み込む */
  83. for(j = 0; j <= m; j++){
  84. recvlen = read(sock[m], buf, sizeof(buf));
  85. if (recvlen <= 0) {
  86. /* クライアント側が EOF */
  87. break;
  88. }
  89. printf(">> %s", buf);
  90. }
  91. }
  92.  
  93. }
  94. /* これ以上クライアントを受け付けないので、サーバのソケットを閉じる */
  95. close(srv_sock);
  96.  
  97. close(sock[m]);
  98. }
  99.  
  100.  
Runtime error #stdin #stdout 0.01s 1716KB
stdin
Standard input is empty
stdout
Standard output is empty