간단한 TCP 서버


104

포트 N에서 들어오는 TCP 트래픽을 수신하는 프로그램이나 함수를 작성하십시오. 간단한 서비스를 제공합니다. 들어오는 연결의 IP 주소 필드의 합계를 계산하고 반환합니다.

프로그램 또는 함수는 인수 또는 stdin에서 정수 N을 읽습니다. 포트 N에서 들어오는 TCP 연결을 수신합니다. 누군가 해당 포트에 연결하면 프로그램은 IP 주소 필드의 합계를 계산하여 후행 줄 바꿈을 사용하여 클라이언트로 다시 보내고 연결을 닫습니다.

  • 포트 번호 N은 유효한 포트이며 2 10 <N <2 15
  • 후행 줄 바꿈은 \n또는\r\n
  • IPv4 또는 IPv6을 사용할 수 있습니다. IPv6 주소는 16 진 형식으로 작성되므로 예를 들어 같은 형식으로 결과를 제공해야합니다 2001:0db8:0000:0042:0000:8a2e:0370:7334 => 12ecd.

이것은 입니다. 표준 규칙 및 허점이 적용됩니다.

로 서버를 실행합니다 ./server 1234. 서버가 이제 실행 중이고 포트 1234에서 127.0.0.1연결을 기다리고 있습니다. 그런 다음 클라이언트가 서버에 연결됩니다. 서버는 간단한 계산을 수행 127+0+0+1 => 128하고 결과를 클라이언트에게 보냅니다 (후행 줄 바꿈) 128\n. 그런 다음 서버는 연결을 닫고 다음 클라이언트를 기다립니다.

리더 보드

var QUESTION_ID=76379,OVERRIDE_USER=20569;function answersUrl(e){return"https://api.stackexchange.com/2.2/questions/"+QUESTION_ID+"/answers?page="+e+"&pagesize=100&order=desc&sort=creation&site=codegolf&filter="+ANSWER_FILTER}function commentUrl(e,s){return"https://api.stackexchange.com/2.2/answers/"+s.join(";")+"/comments?page="+e+"&pagesize=100&order=desc&sort=creation&site=codegolf&filter="+COMMENT_FILTER}function getAnswers(){jQuery.ajax({url:answersUrl(answer_page++),method:"get",dataType:"jsonp",crossDomain:!0,success:function(e){answers.push.apply(answers,e.items),answers_hash=[],answer_ids=[],e.items.forEach(function(e){e.comments=[];var s=+e.share_link.match(/\d+/);answer_ids.push(s),answers_hash[s]=e}),e.has_more||(more_answers=!1),comment_page=1,getComments()}})}function getComments(){jQuery.ajax({url:commentUrl(comment_page++,answer_ids),method:"get",dataType:"jsonp",crossDomain:!0,success:function(e){e.items.forEach(function(e){e.owner.user_id===OVERRIDE_USER&&answers_hash[e.post_id].comments.push(e)}),e.has_more?getComments():more_answers?getAnswers():process()}})}function getAuthorName(e){return e.owner.display_name}function process(){var e=[];answers.forEach(function(s){var r=s.body;s.comments.forEach(function(e){OVERRIDE_REG.test(e.body)&&(r="<h1>"+e.body.replace(OVERRIDE_REG,"")+"</h1>")});var a=r.match(SCORE_REG);a&&e.push({user:getAuthorName(s),size:+a[2],language:a[1],link:s.share_link})}),e.sort(function(e,s){var r=e.size,a=s.size;return r-a});var s={},r=1,a=null,n=1;e.forEach(function(e){e.size!=a&&(n=r),a=e.size,++r;var t=jQuery("#answer-template").html();t=t.replace("{{PLACE}}",n+".").replace("{{NAME}}",e.user).replace("{{LANGUAGE}}",e.language).replace("{{SIZE}}",e.size).replace("{{LINK}}",e.link),t=jQuery(t),jQuery("#answers").append(t);var o=e.language;/<a/.test(o)&&(o=jQuery(o).text()),s[o]=s[o]||{lang:e.language,user:e.user,size:e.size,link:e.link}});var t=[];for(var o in s)s.hasOwnProperty(o)&&t.push(s[o]);t.sort(function(e,s){return e.lang>s.lang?1:e.lang<s.lang?-1:0});for(var c=0;c<t.length;++c){var i=jQuery("#language-template").html(),o=t[c];i=i.replace("{{LANGUAGE}}",o.lang).replace("{{NAME}}",o.user).replace("{{SIZE}}",o.size).replace("{{LINK}}",o.link),i=jQuery(i),jQuery("#languages").append(i)}}var ANSWER_FILTER="!t)IWYnsLAZle2tQ3KqrVveCRJfxcRLe",COMMENT_FILTER="!)Q2B_A2kjfAiU78X(md6BoYk",answers=[],answers_hash,answer_ids,answer_page=1,more_answers=!0,comment_page;getAnswers();var SCORE_REG=/<h\d>\s*([^\n,]*[^\s,]),.*?(\d+)(?=[^\n\d<>]*(?:<(?:s>[^\n<>]*<\/s>|[^\n<>]+>)[^\n\d<>]*)*<\/h\d>)/,OVERRIDE_REG=/^Override\s*header:\s*/i;
body{text-align:left!important}#answer-list,#language-list{padding:10px;width:290px;float:left}table thead{font-weight:700}table td{padding:5px}
<script src="https://ajax.googleapis.com/ajax/libs/jquery/2.1.1/jquery.min.js"></script> <link rel="stylesheet" type="text/css" href="//cdn.sstatic.net/codegolf/all.css?v=83c949450c8b"> <div id="answer-list"> <h2>Leaderboard</h2> <table class="answer-list"> <thead> <tr><td></td><td>Author</td><td>Language</td><td>Size</td></tr></thead> <tbody id="answers"> </tbody> </table> </div><div id="language-list"> <h2>Winners by Language</h2> <table class="language-list"> <thead> <tr><td>Language</td><td>User</td><td>Score</td></tr></thead> <tbody id="languages"> </tbody> </table> </div><table style="display: none"> <tbody id="answer-template"> <tr><td>{{PLACE}}</td><td>{{NAME}}</td><td>{{LANGUAGE}}</td><td>{{SIZE}}</td><td><a href="{{LINK}}">Link</a></td></tr></tbody> </table> <table style="display: none"> <tbody id="language-template"> <tr><td>{{LANGUAGE}}</td><td>{{NAME}}</td><td>{{SIZE}}</td><td><a href="{{LINK}}">Link</a></td></tr></tbody> </table>


1
inetd / xinetd 또는 이와 유사한 것을 사용할 수 있습니까?
Digital Trauma

91
골프 언어가 그다지 능숙하지 않다는 것은 골프 과제이기 때문에 나는 이것을 좋아합니다.
isaacg

9
TCP 서버가 작성하기가 매우 쉬운 프로그램이라는 것은 놀라운 일일뿐만 아니라 재미를 위해 골프를 치고 있다는 사실에 철저히 기초하고 있습니다. 난 그냥 막연한 것처럼 FizzBuzz와 고군분투로 돌아갑니다.
MonkeyZeus

17
@isaacg 누군가가 Mathematica
Downgoat

3
@MonkeyZeus 공평하게, 당신은 여기에 좋은 TCP 서버를 볼 수 없습니다 . 신뢰성, 확장 성 TCP의 TCP (및 응용 프로그램 프로토콜)의 모든 복잡성을 처리하는 서버도 조금 어렵 만들기 : 그것은 확실히 프로토콜은 상당히 간단하다는 데 도움이 있지만 D를 - 당신도 할 필요가 없습니다 읽을 스트림을, 뭔가 내가 계산하기에 너무 많은 TCP 서버에서 고장난 것을 보았습니다 : D
Luaan

답변:


57

Bash + netcat + ss +…, 65 60 자

nc -lp$1 -c'ss src :'$1'|awk \$0=\$5|tr .: +#|bc'
exec $0 $1

심각한 해결책은 아니며,이 가능성에 대해 궁금했습니다.

덕분에 :

  • awk기반 필터링 을 제안하기위한 ninjalj (-5 자)

샘플 실행 :

(터미널 1)

bash-4.3$ ./ip-reduce.sh 8080

(터미널 2)

bash-4.3$ nc localhost 8080
128

bash-4.3$ telnet localhost 8080
Trying 127.0.0.1...
Connected to localhost.
Escape character is '^]'.
128
Connection closed by foreign host.

우분투에서 당신은 얻을 수 nc에서 netcat을 전통적인 (아니, netcat을-오픈 BSD는 좋지 않다)과 ss에서 iproute2를 .


22
왜 이것이 심각한 해결책이 아니라고 말합니까? 그것이 예상대로 작동하는 한 나는 그것이 심각하게 여겨져서는 안되는 이유를 알 수 없습니다. 또한 현재로서는 상당히 큰 마진으로 가장 짧습니다.
Alex A.

IPv6이 구성된 시스템에서 소켓 관련 정보의 형식이 다를 수 있다는 사실을 알았을@JesseSielaff와의 토론 중에 가장 큰 우려가 나타났습니다 . 테스트 할 시스템이 없습니다. 이를 위해 CW로 전환하는 것이 더 올바른지 여부를 생각하고 있습니다.
manatwork

3
사양에 대한 이해는 IPv4 또는 IPv6을 모두 지원해야한다는 것 입니다. 따라서 IPv6을 지원하지 않는 IPv4에서 작동하는 한 중요하지 않다고 생각합니다.
Alex A.

1
@AlexA. 적어도 내 질문에 그렇게 생각합니다. 명확히해야합니까?
Hannes Karppila

@HannesKarppila, 귀하의 질문은 분명합니다. 가능한 문제는 솔루션을 실행하기 위해 운영 체제를 특정 방식으로 구성해야 할 수도 있다는 것입니다. 따라서 처리 여부에 관계없이 IPv6을 구성하면 실패 할 수 있기 때문에 걱정입니다. IPv6을 구성한 사람은 확실히 말할 수 있습니다…
manatwork

23

C #을, 284 283 282 278 274 254 바이트

class A{static int Main(string[]a){var b=new System.Net.Sockets.TcpListener(int.Parse(a[0]));b.Start();for(;;){var c=b.AcceptTcpClient();var d=c.Client.LocalEndPoint.Serialize();new System.IO.StreamWriter(c.GetStream()).WriteLine(d[4]+d[5]+d[6]+d[7]);}}}

기본 C # TCP 서버의 고전적인 예. 테스트 :

터미널 1:

$ ./Q76379.exe 1029

터미널 2:

$ telnet localhost 1029
Trying 127.0.0.1...
Connected to localhost.
Escape character is '^]'.
128
Connection closed by foreign host.

Firefox :


7
int Main대신을 사용하여 1 바이트를 저장할 수 있습니다 void Main. 프로그램이 컴파일러를 반환하지 않으므로 return명령문이 필요하지 않습니다 .
raznagul

그리고, 누출되지 않습니다. 실제로 리소스를 공개하는 것도 결정적입니다. 또한 인수 Start는 선택 사항이므로 다른 문자를 저장합니다.
Luaan

@Luaan 그래, 그것은 디버깅에서 남았다.
LegionMammal978

또한, 사용할 수있는 usingTcpClient당신에게 세 이상의 문자를 저장합니다 (을 사용하는 {}으로부터 for)와 함께 같은 일을 StreamWriter한 번 더 저장해야합니다.
Luaan

@Luaan 나는 명시 적으로 필요 Flush(가) StreamWriter제대로 작동하도록.
LegionMammal978

22

Linux ELF / x86, 146 바이트

00000000  7f 45 4c 46 01 00 00 00  5a 0e 00 00 5a 5e eb 10  |.ELF....Z...Z^..|
00000010  02 00 03 00 0c 50 eb 10  0c 50 eb 10 04 00 00 00  |.....P...P......|
00000020  5e 53 43 53 52 89 e1 b0  66 3d 20 00 01 00 cd 80  |^SCSR...f= .....|
00000030  97 55 6b ed 0a 01 c5 ac  2c 30 79 f6 43 0f cd 01  |.Uk.....,0y.C...|
00000040  dd 55 89 e1 6a 10 51 6a  10 51 57 89 e1 b0 66 cd  |.U..j.Qj.QW...f.|
00000050  80 43 43 b0 66 cd 80 01  64 24 08 89 e1 43 b0 66  |.CC.f...d$...C.f|
00000060  cd 80 89 c1 93 8d 74 24  1b 99 fd ac 01 c2 e2 fb  |......t$........|
00000070  89 f7 b0 0a aa 91 92 f6  f1 86 c4 04 30 aa 42 c1  |............0.B.|
00000080  e8 08 75 f3 42 89 f9 41  b0 04 cd 80 b0 06 cd 80  |..u.B..A........|
00000090  eb c9                                             |..|
00000092

헤더 내부를 건너 뛸 수 있도록 52 바이트 ELF 헤더, 32 바이트 프로그램 헤더, 111 바이트의 프로그램 코드 + 3 바이트의 코드를 포함합니다.

작은 ELF 실행 파일을 만드는 방법에 대한 정보는에서 찾을 수 있습니다 식빵 창고" 리눅스에 대한 정말 얼른 ELF 실행 파일을 만들기에 회오리 바람 튜토리얼 " .

Linux / i386은 특정 소켓 호출 (에서 매크로 ) 및 원래 라이브러리 호출의 인수 영역 에 대한 포인터를 socketcall(2)취하는 멀티 플렉스 시스템 호출을 사용합니다 .ebxSYS_*/usr/include/linux/net.hecx

실행 파일을 작게 유지하기 위해 수행 한 몇 가지 작업 :

  • Linux에서와 같이 시작시 레지스터가 0으로 설정되어 있지만 ELF 표준에서는 필요하지 않습니다 (유일한 요구 사항은 입력 EDX이 종료 기능 (동적 링커에서로드 한 실행 파일에 유용함)을 가리키는 것 또는 NULL 임)입니다.
  • 시작시 (일반적으로 쉘에 의해) 열린 파일 설명 자만 0, 1 및 2라고 가정합니다. 이는 청취 소켓이 fd 3이고 허용되는 소켓이 fd 4임을 의미합니다.
  • 정확히 2 개의 인수 (포함 argv[0]) 가 있다고 가정합니다 .
  • 같은 스택 공간에 대한 호출을 위해 재사용 bind(2), listen(2)하고 accept(2).
  • phentsizeand phnum필드 를 건너 뛰기 위해 바이트가 앞에 추가 CMP되어 phentsizeand phnum필드를 즉시 처리 하는 작업 으로 바뀝니다 (빵 상자 솔루션 에서 무질서하게 도난당한 아나키 골프에서 123 ).
  • x86 문자열 연산 LODS(누산기 및 증분 / 감소 소스 인덱스로로드) 및 STOS(누산기 및 증분 / 감소 대상 인덱스에서 저장)는 짧은 코드에 적합합니다.
  • XCHG EAX, reg에 비해 1 바이트이며 MOV EAX, reg2 바이트가 걸립니다.
  • CDQ/CLTD(sign-extend EAXinto EDX:EAX)는 EDX레지스터 를 0으로 만드는 1 바이트 방식으로 사용될 수 있습니다 .
  • BSWAP구현에 유용합니다 htons().

nasm 소스 :

BITS 32                                         ;
                                                ;   ELF HEADER    --   PROGRAM HEADER
; ELF HEADER                                    ; +-------------+
DB 0x7f,'E','L','F'                             ; | magic       |    +--------------------+
                                                ; |             |    |                    |
; PROGRAM HEADERS                               ; |             |    |                    |
DD 1                                            ; |*class   32b | -- | type: PT_LOAD      |
                                                ; |*data   none |    |                    |
                                                ; |*version   0 |    |                    |
                                                ; |*ABI    SysV |    |                    |
DD 0xe5a        ; offset = vaddr & (PAGE_SIZE-1); |*ABI vers    | -- | offset             |
                                                ; |             |    |                    |
entry:  pop     edx     ; edx = 2 (argc)        ; |*PADx7       | -- | vaddr = 0x10eb5e5a |
        pop     esi     ; discard argv[0]       ; |             |    |                    |
        jmp     short skip                      ; |             |    |                    |
DW 2                                            ; | ET_EXEC     | -- |*paddr LO           |
DW 3                                            ; | EM_386      | -- |*paddr HI           |
DD 0x10eb500c                                   ; |*version     | -- | filesz             |
DD 0x10eb500c                                   ; | entry point | -- | memsz              |
DD 4                                            ; | ph offset   | -- | flags: RX          |
                                                ; |             |    |                    |
skip:   pop     esi     ; esi = argv[1]         ; |*sh offset   | -- |*align              |
socket: push    ebx     ; default protocol (0)  ; |             |    |                    |
        inc     ebx                             ; |             |    |                    |
        push    ebx     ; SOCK_STREAM (1)       ; |             |    |                    |
        push    edx     ; AF_INET (2)           ; |*flags       |    +--------------------+
        mov     ecx, esp                        ; |             |
        mov     al, 0x66                        ; |*ehsize      |
DB 0x3d         ; cmp eax,0x10020               ; |             |
DW 32                                           ; | phentsize   |
DW 1                                            ; | phnum       |
                                                ; |             |
        int     0x80    ; socket(2, 1, 0)       ; |*shentsize   |
        xchg    edi, eax; edi = sockfd, eax = 0 ; |*shnum       |
        push    ebp     ; INADDR_ANY            ; |             |
                                                ; |             |
mult:   imul    ebp, 10 ; \_                    ; |*shstrndx    |
        add     ebp, eax; >                     ; |             |
        lodsb           ; >                     ; +-------------+
        sub     al,'0'  ; >
        jns     mult    ; / ebp = atoi(argv[1])                 ;       bind stack frame
                                                                ;    +-----------------------+
endmul: inc     ebx             ; SYS_BIND (2)                  ;    |        INADDR_ANY     |
                                                                ; +->| AF_INET | htons(port) |
        bswap   ebp                                             ; |  +-----------------------+
        add     ebp, ebx        ; AF_INET (2), htons(port)      ; |  |           16          |
        push    ebp                                             ; |  +-----------------------+
                                                                ; |  |         dummy         |
        mov     ecx, esp                                        ; |  +-----------------------+
        push    16              ; addrlen                       ; |  |           16          |
        push    ecx             ; dummy value                   ; |  +-----------------------+
        push    16              ; addrlen                       ; +--|          addr         |
        push    ecx             ; addr                          ;    +-----------------------+
        push    edi             ; sock                          ;    |         sockfd        |
        mov     ecx, esp                                        ;    +-----------------------+
        mov     al, 0x66
        int     0x80            ; bind(sockfd, addr, addrlen)
                                                                ;       accept stack frame
                                                                ;    +-----------------------+
listen: ;mov    byte [esp+8],1                                  ;    |        INADDR_ANY     |
        inc     ebx                                             ; +->| AF_INET | htons(port) |
        inc     ebx             ; SYS_LISTEN (4)                ; |  +-----------------------+
        mov     al, 0x66                                        ; |+>|           16          |
        int     0x80            ; listen(sockfd, backlog)       ; || +-----------------------+
                                                                ; || |         dummy         |
        add     [esp+8], esp                                    ; || +-----------------------+
accept: mov     ecx, esp                                        ; |+-|        &addrlen       |
        inc     ebx             ; SYS_ACCEPT (5)                ; |  +-----------------------+
        mov     al, 0x66                                        ; +--|          addr         |
        int     0x80            ; accept(sockfd, addr, &addrlen);    +-----------------------+
                                                                ;    |         sockfd        |
        mov     ecx, eax        ; ecx = 4                       ;    +-----------------------+
        xchg    ebx, eax        ; ebx = acceptfd, eax = 000000xx

        lea     esi, [esp+27]   ; point to the IP part of struct sockaddr_in
        cdq

        std                     ; reverse direction for string operations
addip:  lodsb                   ; \_
        add     edx, eax        ; > edx = sum of 4 IP bytes
        loop    addip           ; /

        mov     edi, esi        ; reuse struct sockaddr_in as scratch buffer
        mov     al, 10          ; '\n'
        stosb
        xchg    ecx, eax        ; ecx = 10
        xchg    eax, edx        ; edx = 0, eax = sum

divide: div     cl              ; \_
        xchg    al, ah          ; >
        add     al,0x30         ; >
        stosb                   ; > sprintf(scratch, "%d", sum)
        inc     edx             ; >
        shr     eax, 8          ; >
        jnz     divide          ; /

write:  inc     edx             ; ndigits + 1 ('\n')
        mov     ecx, edi
        inc     ecx
        mov     al,4
        int     0x80            ; write(acceptfd, scratch, scratchlen) 
close:  mov     al, 6
        int     0x80            ; close(acceptfd)
        jmp     accept

4
이 답변은 과소 평가되었습니다.
고양이

16

NodeJS, 146 (134) 127 바이트

require('http').createServer((q,s)=>s.end(eval(0+q.socket.remoteAddress.replace(/^.*:|\./g,'+'))+'\n')).listen(process.argv[2])

마침내 NodeJS 답변을 게시 할 수 있습니다! IPv4 만 가능합니다.

샘플 실행 : node script.js 1024. 다른 터미널에서 :

$ curl 127.0.0.1:1024
128

2
'\n'리터럴 줄 바꿈이 포함 된 템플릿 문자열 로 교체하여 126 바이트로 줄일 수는 있지만 지금은 127 바이트를 계산 합니다.
Mwr247

HTTP 서버를 생성하기 때문에 요구 사항에 실패하지 않습니까? 기술적으로 TCP 서버이지만 TCP 모듈을 사용하고 문자를 저장할 수는 없었습니까?
MayorMonty

14

Tcl, 92

  • @DonalFellows 덕분에 1 바이트가 절약되었습니다.
proc s {c a p} {puts $c [expr [string map .\ + $a]]
close $c}
socket -server s $argv
vwait f

상당히 자명 한 설명 :

socket -server s $argv 인수에 지정된 포트에 청취 소켓을 작성합니다.

새 연결이 도착할 때마다 proc s채널, 소스 주소 및 소스 포트를 매개 변수로 사용 하여 가 호출됩니다. string map대체 .를위한 +소스 주소 및 expr산술적 인 다음 결과, 평가 puts다시 접속 채널을 c.

vwait 들어오는 연결 이벤트를 포착하기 위해 이벤트 루프를 실행합니다.


다음에 대해 @DonalFellows에게 기여합니다 :

다음은 IPv6을 처리하는 버전입니다 (Tcl 8.6 필요, 추가 길이는 16 진 응답을 생성하기 때문 임).

Tcl, 109

proc s {c a p} {puts $c [format %x [expr 0x[string map :\ +0x0 $a]]]
close $c}
socket -server s $argv
vwait f

1
사용 apply하면 아무것도 저장되지 않는 것 같습니다. tcl::mathop::+ {*}[split $a .]조금 더 길어서는 사용할 수 없습니다 . 옵션 이름에서 어떤 것도 면도 할 수 없습니다. 그러나 IPv6 지원은 추가하기가 쉽지 않으며 몇 바이트의 코드 만 추가하면됩니다 regsub.
Donal Fellows

아아, Tcl / Tcl-DP ... 놀라운 도구들. (90 년대 교수는 서버에 대해 (iirc) 4 (짧은) 줄과 클라이언트 5를 가진 여러 사람이 공유하는 네트워크 분산 Excel (그리드가 있고 수식 평가 포함)을 작성할 수 있음을 보여주었습니다. ..
Olivier Dulac

proc s {c a p}공백이 정말로 필요합니까?
cat

12

그루비 133 , 125 , 93 , 89

new ServerSocket(args[0]as int).accept{it<<(it.inetAddress.address as int[]).sum()+"\n"}

아마도 IPv4에만 해당됩니다.

언 골프 드 :

new ServerSocket(args[0]as int).accept{
    it << (it.inetAddress.address as int[]).sum()+"\n"
}

테스트 :

$ telnet localhost 9000
Trying 127.0.0.1...
Connected to localhost.
Escape character is '^]'.
128
Connection closed by foreign host.

1
.toInteger()as ints.inetAddress.address*.toInteger()(s.inetAddress.address as int[]). 그리고 이후에 여분의 공간이 .with있습니다.
manatwork

@manatwork thx! 업데이트되었습니다.
Will Lp

9

파이썬 3 170 166 147 바이트

from socket import*
s=socket()
s.bind(("",int(input())))
s.listen()
while 1:
 c,a=s.accept()
 c.send(b"%d\n"%eval(a[0].replace(".","+"))),c.close()

stdinIPv4 전용 포트를 사용 합니다. GNU / 리눅스 (그리고 대부분의 다른 유니스들)에서 작동하며, ""를 "0.0.0.0"으로 자동 확장하지만 Windows에 대해서는 확실하지 않습니다.


2
몇 바이트를 절약 할 수 있습니다. 먼저, 공백 import *, SOCK_STREAM불필요하다. 또한 송신 라인을보다 효율적으로 작성할 수 있습니다 c.send(b"%d\n"%eval(a[0].replace(".","+"))).
Hannes Karppila

2
@HannesKarppila 아, 감사합니다. 공간을 잊어 버렸지 만 평가판 핵은 꽤 시원합니다.
sammko

2
AF_INET 및 SOCK_STREAM은 상수입니다. AF_INET은 2이고 SOCK_STREAM은 1입니다. 또한 언급했듯이 SOCK_STREAM은 필요하지 않습니다. 대신을 사용하여 단축시킬 수 있습니다 s=socket(2).
Skyler

1
socket ()을 수행하여 다른 바이트를 저장할 수는 없습니까?
Foon

1
당신은 그런 파이썬 2를 사용하여 10 개 개의 문자를 저장할 수 int(input())됩니다 input()및 송신 부분이된다c.send(`eval(a[0].replace(".","+"))`)
블렌더

9

자바 371 368 350 344 333 310 295 282 바이트

골프

import java.net.*;class A{public static void main(String[]n)throws Exception{ServerSocket s=new ServerSocket(Integer.decode(n[0]));for(;;){try(Socket a=s.accept()){byte[]c=a.getInetAddress().getAddress();new java.io.PrintStream(a.getOutputStream()).println(c[0]+c[1]+c[2]+c[3]);}}}}

언 골프

import java.net.*;

class A {
    public static void main(String[] n) throws Exception {
        ServerSocket s = new ServerSocket(Integer.decode(n[0]));
        for (;;) {
            try (Socket a = s.accept()) {
                byte[] c = a.getInetAddress().getAddress();
                new java.io.PrintStream(a.getOutputStream()).println(c[0] + c[1] + c[2] + c[3]);
            }
        }
    }
}

산출

mallard@steamroller:~$ telnet localhost 8888
Trying 127.0.0.1...
Connected to localhost.
Escape character is '^]'.
128
Connection closed by foreign host.

1
를 제거하고의 int k=모든 c 항목으로 k를 교체하십시오 Integer.toString(k). 몇 바이트를 절약합니다.
GiantTree

1
Javas 바이트는 192.168.2.1 또는 127을 초과하는 바이트로 유사한 주소에 대한 반환 값을 엉망으로
만듭니다

1
변경 interface하려면 class몇 바이트 확보해야
오르티스

2
a.getOutputStream().write((c[0] + c[1] + c[2] + c[3]+"\n").getBytes());대신 사용new DataOutputStream(a.getOutputStream()).writeBytes(c[0] + c[1] + c[2] + c[3] + "\n")
ortis

3
아닌가 try(Socket a=...){}보다 짧은 a.close();? Java 7이 필요하지만 바이트를 얻을 수 있습니다.
Olivier Grégoire

8

PowerShell을 V2 +, 303 (268) 257 227 바이트

nal n new-object;($l=n Net.Sockets.TcpListener($args[0])).Start()
for(){($w=n IO.StreamWriter(($c=$l.AcceptTcpClient()).GetStream())).Write((([Net.IPEndPoint]$c.Client.RemoteEndPoint).Address-replace"\.",'+'|iex))
$w.Dispose()}

Matt 덕분에 35 바이트 절약 ... 앨리어싱 New-Object및 약간의 조정으로 11 바이트 더 절약 ... anyIP 주소 대신 로컬 호스트를 사용하여 암시 적으로 30 바이트 더 절약 하고 원래 지정된대로 계속 사용하도록 수정했습니다.

C # answer 와 거의 유사 합니다. 두 가지 모두 .NET이기 때문입니다. PowerShell의 반환 기능을 사용하여 (Parens로 선언 / 할당을 둘러싼 다음 즉시. 메서드를 호출하여) C # 답변에 몇 바이트를 절약 할 수 있지만 합계를 공식화해야하므로 많은 손실이 발생합니다. . 우리가 클래스 이름 / 호출을 약간 짧게했다는 사실은 실제로이 답변이 C #을 때리는 이유입니다.

설명

먼저 다시 입력 할 때 절약 New-Aliasnal별칭 ( 별칭 포함)을 만듭니다 New-Object. 첫 번째 줄의 나머지 부분은 TCP 리스너를 설정하는 것입니다. $args[0]새로운 System.Net.Sockets.TcpListener을 저장 하기위한 입력으로 명령 행 을 전달합니다 $l. 그 객체는 parens로 캡슐화되어 즉시 .Start()소켓을 열도록 호출됩니다 .

무한 for루프에 들어가면 리스너 $l를 블로킹으로 설정 AcceptTcpClient()하여 연결을 기다립니다. 해당 연결에 대한 참조 (한 번 만들어진)는에 저장되고 $c, 괄호 안에 캡슐화되며, 즉시 GetStream()데이터 스트림을 가져 오기 위해 호출 됩니다. 이 데이터 스트림은 새로운 System.IO.StreamWriter생성자 로 전달 $w되므로이를 조작 할 수 있습니다. 그 생성자 자체는 parens로 캡슐화되어 즉시 호출 Write(...)됩니다.

Write(...)호출 안에서 , 우리는 클라이언트 핸들 $c을 가져 와서 클라이언트의 RemoteEndPoint속성을 얻습니다 . 이것이 지금까지 찾은 원격 IP 주소를 얻는 유일한 방법입니다. 다음으로 우리는 [System.Net.IPEndPoint]그것을 객체 로 다시 캐스팅하여 올바르게 포맷되고, 그것을 괄호로 캡슐화하고, .Address속성 만 가져와야 합니다. 그런 다음 -replace문자 기호에 더하기 부호가 붙은 다음 이 기호를 Invoke-Expression(와 비슷하게 eval) 파이프하여 요약을 얻습니다.

IO 쓰기 후 .Dispose()데이터 스트림이 클라이언트로 플러시되고 닫히 도록 호출해야합니다 . TCP 서버는 경고없이 클라이언트 연결을 끊으므로 사용 된 클라이언트에 따라이 시점에서 잠시 중단 될 수 있습니다. 그런 다음 for연결을 올바르게 닫지 않고 루프 를 계속 진행 합니다. 이것은 또한 메모리와 시스템 핸들이 미친 것처럼 누출되지만 우리는 신경 쓰지 않습니다. 그러나 서버 실행이 끝나면 작업 관리자를 사용하여 프로세스를 종료해야 할 수도 있습니다. :디

또한 요약 막대가 IPv6 주소를 처리하려고 시도하는 것처럼 IPv4 전용 입니다. 구문 분석에 :유효한 대수 연산자가 아니기 때문 입니다 iex.


2
"기억처럼 메모리와 시스템 핸들이 누출됩니다" 무엇을해야 free()합니까? delete[], 아마도? : P
고양이

8
@tac 그래, 전체의 회전있다 .close().dispose()발작을 가지고 코드 검토에 사람을 야기 우리가 여기 호출하지 않는 방법.
AdmBorkBork

PS GC가 아닌가? 아니면 GC는 범위 분석이 아닌 재검토를 수행합니까?
고양이

@tac 예, PowerShell에는 기본 .NET 시스템 덕분에 가비지 수집 기능 이 있습니다 . 그러나, 당신은 전화 또는이 스크립트를 활용하는 방법에 따라, 당신은 같은 버그로 실행 이 하나의 파이프 라인에서 메모리가 누수. 위의 코드는 스레드 안전하지 않으므로 소켓을 명시 적으로 닫지 않기 때문에 GC 문제가 발생할 수 있습니다.
AdmBorkBork

1
테스트 할 때 방화벽 문제로 인해 문제가 해결되지 않을 수 있으므로 확신 할 수는 없지만 ..... 모든 유형의 캐스트가 아닌 경우 대부분 "시스템"을 삭제할 수 있다고 생각합니다. 당신은 즉 : [Net.ipaddress]::Any작품.
Matt

7

PHP, 161 (56?)

이것은 나의 첫 번째 게시물입니다. 나는 이것이 잘되기를 바랍니다 :)

<?php $s=socket_create_listen($argv[1]);while($c=socket_accept($s)){socket_getpeername($c,$r);socket_write($c,array_sum(explode('.',$r))."\n");socket_close($c);}

언 골프 드 :

<?php 
    $s = socket_create_listen($argv[1]); //Create socket
    while( $c = socket_accept($s) ) { // Loop accepting new connections
        socket_getpeername($c, $r); // Get IP address in $r
        socket_write($c, array_sum(explode('.', $r))."\n"); //Calculate sum
        socket_close($c); //Close connection and wait for next one
    }

단말기:

$ php test.php 8080 &
$ telnet localhost 8080
Trying 127.0.0.1...
Connected to localhost.
Escape character is '^]'.
128
Connection closed by foreign host.

이것은 IPV4에서만 작동합니다

편집 : 방금 PHP가 기본 서버를 지원한다는 것을 알았습니다.
누군가 다음이 허용되는지 확인하지 않으면 원래 문자 수를 고수하기로 결정했습니다 . :)

test2.php : (56 바이트 솔루션 가능)

<?=array_sum(explode('.',$_SERVER['REMOTE_ADDR']))."\n";

그런 다음 서비스를 시작하십시오.

php -S localhost:8080 test2.php

클라이언트로서의 크롬 스크린 샷

편집 2 : 클라이언트로 wget

$ wget -qO- localhost:8080
128

규칙에 따르면 "프로그램 또는 함수가 인수 또는 stdin에서 정수 N을 읽습니다."라고 말하지만이 경우 프로그램이 PHP 자체이면 괜찮습니까? 아니면 PHP에서 내장 서버를 사용하는 것이 허점으로 간주됩니까?
Mikael

프로그래밍 퍼즐 및 코드 골프에 오신 것을 환영합니다! 161 바이트 솔루션은 훌륭해 보입니다. 56 바이트 솔루션이 아래에 언급되어 test2.php있습니까? 그렇다면 OP에 문의하여 이러한 도전에 대해 해당 유형의 내장 기능을 허용하는지 고려해야한다고 생각합니다. 그래도 허점이 아닙니다.
Alex A.

내장 TCP 서버를 사용하는 것은 괜찮지 만이 경우 내장 HTTP 서버에 대해 이야기 합니다 . 따라서 56 바이트 솔루션 1) 클라이언트가 연결하고 아무것도 보내지 않으면 아무것도하지 않습니다. 2) 클라이언트가 "foo"를 보내는 경우 test2.php를 실행하지 않고 "[수 3 월 30 일 10:15:02 2016] 127.0.0.1:47974 잘못된 요청 (잘못된 HTTP 요청)"만 다시 보냅니다. 3) 클라이언트가 유효한 HTTP 요청을 보내는 경우 실제 필요한 응답 전에 전체 HTTP 응답 헤더 세트를 보냅니다.
manatwork

@Alex A. 감사합니다. 예, 56 바이트 솔루션은 test2.php에 있습니다 :)
Mikael

@manatwork 당신은 정확하지만이 작업에서 클라이언트가 명확하게 지정되지 않았다고 생각했습니다. 브라우저 나 "wget ​​-qO- localhost : 8080"같은 클라이언트를 클라이언트로 사용해도 괜찮습니까?
Mikael

7

이동 , 359 (311)

이것은 Go의 첫 번째 프로그램입니다. 한 가지를 발견하게 해주었습니다. 이것은 확실히 좋은 골프 언어는 아닙니다!

(골프의 대부분을했던 @steve에게 Kudos!)

package main
import(n"net";t"strings";r"strconv";x"regexp";"os")
func main(){l,_:=n.Listen("tcp",":"+os.Args[1])
for{c,_:=l.Accept();var s int
for _,i:=range t.Split(x.MustCompile(":[0-9]+$").ReplaceAllLiteralString(c.RemoteAddr().String(),""),"."){
n,_:=r.Atoi(i);s=s+n};c.Write([]byte(r.Itoa(s)));c.Close()}}

2
그러나 그것은 tcp 서버를 만들기에 좋은 언어입니다!
Numeri

1
홀수, 427이 아닌 192.168.0.67에서 연결할 때 결과 360을 얻습니다.
steve

3
strings + strconv 패키지의 이름을 지정하여 몇 바이트를 절약 할 수 있습니다. 예를 들어이 "strings"되고 s "strings"나중에는 수 있도록 strings.Split단지가된다 s.Split.
steve

1
pastebin.com/HY84sazE에서 더 많은 바이트를 삭감
steve

2
import(."pkgname")모든 함수 를 사용 하면 현재 네임 스페이스로 가져 오면 접두사를 삭제할 수 있습니다. 예. import ."fmt"; Println("foo") 당신이 사용하는 경우 Sscanf로부터 fmt주소를 구문 분석 패키지 대신 정규식의 그것은 당신에게 가지고있는 좋은 보너스를주고, 당신에게 다른 몇 바이트를 절약 할 수 있습니다 Fprintln전체를 반환하는 대신 가져가 strconv.
Kristoffer Sall-Storgaard 2016 년

7

공통 리스프, 110 바이트

(use-package'usocket)(lambda(p)(socket-server"localhost"p(lambda(u)(format u"~D~%"(reduce'+ *remote-host*)))))

세부

(use-package 'usocket)

(lambda (port)

  ;; create server with event-loop
  (socket-server "localhost"
                 port

                 ;; tcp-handler
                 (lambda (stream)
                   ;; format to stream to client
                   (format stream
                           "~D~%"
                           ;; add all elements of the host,
                           ;; a vector of 4 integers
                           (reduce #'+ *remote-host*))

                   ;; client connection is closed automatically
                   ;; when exiting this function                     
                 )))

2
일반적인 Lithp를위한 Yay!
cat

6

q, 88 바이트

system raze"p ",1_.z.x;.z.pg:{(string sum"i"$0x0 vs .z.a),"\n"};.z.ph:{.h.hy[`;.z.pg[]]}
  • system raze"p ",1_.z.x: 두 번째 명령 줄 인수 (첫 번째 "-"는 스크립트 / 파일 q로 해석하지 않음 )와 함께 N포트 ( "p ")를 엽니 다 .
    • 참고 : 호출 q -p N은 포트를 N자동으로 설정 하지만 질문은 N실행 파일이 아닌 프로그램에 대한 논쟁이어야한다고 제안하는 것처럼 보이므로 더 먼 길을 갔다.
  • .z.pg들어오는 요청을 처리 하는 함수 내에서 .z.aIP 주소를 32 비트 정수로 유지합니다.
    • "i"$0x0 vs그것을 정수 '구성 요소'로 나누고 sum합산을 수행합니다.
    • 마지막으로 string숫자 결과를 추가 한 "\n"후 클라이언트에 반환합니다.
  • .z.ph 문자열 출력을 유효한 HTTP 응답으로 변환하기위한 추가 처리 기능이있는 HTTP GET 요청을위한 또 다른 기능입니다.

데모-서버 :

c:\q\w32>q - 1234
KDB+ 3.3 2015.11.03 Copyright (C) 1993-2015 Kx Systems
w32/ 4()core ... NONEXPIRE

Welcome to kdb+ 32bit edition
q)system raze"p ",1_.z.x;.z.pg:{(string sum"i"$0x0 vs .z.a),"\n"};.z.ph:{.h.hy[`;.z.pg[]]}
q)

데모-클라이언트 (에서 q실행중인 다른 세션의 127.0.0.1) :

q)(hopen `::1234)""
"128\n"

데모-클라이언트 (에서 curl) :

$ curl localhost:1234
128

$

6

는 LiveScript, 107 105 바이트

(require \http)createServer(->&1.end((.reduce (+))<|it.connection.remoteAddress/\.))listen process.argv.0

추가 할 사항은 없으며 기본 NodeJS입니다. LS에서 &1(두 번째 인수), <|(F # 파이핑, $Haskell 과 유사 ) 및 biop :의 스타일 포인트 는 Haskell의 (+)연산자 섹션과 같습니다. 또한 약간 더러워지면 오른쪽에 리터럴 문자열이 /제공되면 분할됩니다.


5

펄, 141132 + 1 = 133 바이트

골프

$s=new IO::Socket::INET LocalPort=><>,Listen=>5,Reuse=>1;{$c=$s->accept;$_=$c->peerhost;y/./+/;$c->send(eval.$/);shutdown $c,1;redo}

언 골프

# listen on tcp port obtained from stdin
$s=new IO::Socket::INET(LocalPort=> <>,
                        Listen   => 5,
                        Reuse    => 1);

{
    # accept connection
    $c=$s->accept();

    # get the ip address
    $_=$c->peerhost();

    # replace dots with plus
    y/./+/;

    # send the evaluated version back, with a newline
    $c->send(eval . $/);

    # close
    shutdown($c,1);

    redo;
}

$ echo 7777|perl -MIO::Socket::INET -e'$s=new IO::Socket::INET LocalPort=><>,Listen=>5,Reuse=>1;{$c=$s->accept;$_=$c->peerhost;y/./+/;$c->send(eval.$/);shutdown $c,1;redo}'

$ telnet 127.0.0.1 7777
Trying 127.0.0.1...
Connected to 127.0.0.1.
Escape character is '^]'.
128
Connection closed by foreign host.
$

이것이 맞습니까? 클라이언트가 아닌 서버 터미널에 합계가 인쇄됩니다. 어쨌든 모든 괄호를 제거하고 s/\./+/g→을 변경할 수 있습니다 y/./+/.
manatwork

Ahh, misread ..는 그에 따라 수정하고 좋은 y / 제안을 통합합니다.
steve

1
while(1){…}user130144 의 훌륭한 {…;redo} 에 따르면 . 그리고 전화를 제외하고 다른 모든 괄호는 필요하지 않습니다. ->send()
manatwork

4

파이썬 2, 180 바이트

from SocketServer import*
TCPServer(('',input()),type('',(BaseRequestHandler,set),{'handle':lambda s:s.request.send(`eval(s.client_address[0].replace('.','+'))`)})).serve_forever()

stdin을 통해 포트를 사용합니다.


4

NodeJS (ES6) 129 118 107 바이트

require('net').createServer(c=>c.end(eval(c.remoteAddress.replace(/\./g,'+'))+`
`)).listen(process.argv[2])

IPv4에서 작동합니다. 다음으로 실행node server.js <port>


이후 사실, (광산은 자동으로 수행 예를 들어, 같은) 작업 서버의 사용 IPv6의 경우하지 않습니다 c.remoteAddress다음이 될 것입니다 ::ffff:127.0.0.1. (노드 v5.9.1에서 테스트했습니다).
Frxstrem

또한 후행 줄 바꿈이 없으므로 점수가 2 바이트 증가해야합니다.
Frxstrem

@Frxstrem Whoops, 그 개행을 잊었다. 템플릿 문자열 덕분에 1 바이트 만 추가합니다. IP 제품군과 관련하여 : .listen()먼저 IPv4를 기본값으로 사용했지만 버그 나 디자인에 의해 변경된 것으로 보입니다. 호스트 시스템에서 IPv6을 사용하지 않으면 최신 버전의 노드에서 제출이 여전히 올바르게 작동합니다.
Mwr247

4

211 바이트

package main
import(."fmt"
."net"
"os")
func main(){s,_:=Listen("tcp4",":"+os.Args[1])
for{c,_:=s.Accept()
var a,b,d,e int
Sscanf(Sprint(c.RemoteAddr()),"%d.%d.%d.%d",&a,&b,&d,&e)
Fprintln(c,a+b+d+e)
c.Close()}}

예를 들어 IP 주소를 구문 분석 해야하는 방식에 완전히 만족하지는 못합니다. 끔찍한 해킹처럼 보입니다.

인수로 지정된 포트에서 IPv4에서 청취합니다.


4

PowerShell을 208 206 192 152 바이트

($t=[net.sockets.tcplistener]$args[0]).start();for(){($z=$t.acceptsocket()).sen‌d([char[]]"$($z.remoteendpoint.address-replace"\.","+"|iex)");$z.close()}

버전 정보 :

Name                           Value
----                           -----
PSVersion                      4.0
WSManStackVersion              3.0
SerializationVersion           1.1.0.1
CLRVersion                     4.0.30319.34209
BuildVersion                   6.3.9600.17400
PSCompatibleVersions           {1.0, 2.0, 3.0, 4.0}
PSRemotingProtocolVersion      2.2

14 바이트 절약 해 주신 TimmyD에게 감사드립니다!

40 바이트를 절약 해 준 TessellatingHeckler에게 대단히 감사합니다


@TimmyD 아 죄송합니다. 그것이 필요하다는 것을 놓쳤습니다 ... 지금 수정
Nacht

프로그램이 입력을받을 수있는 방법 중 하나는 stdin입니다. 이 특정 질문에 허용 된 것으로 지정하지 않았지만 PowerShell에 대해 계산 해야하는 일반적인 코드 골프 일이라고 가정합니다. 불행히도 bash와는 다르며 stdin에서 입력을 제공하지 않으면 입력을 기다리지 않습니다.
Nacht

그럴 수 있지. 다시 수정
Nacht

좋아, 이제 일부 골프의 경우-192에서 다음을 시도해보십시오 –($t=new-object net.sockets.tcplistener($args[0])).start();for(){($z=$t.acceptsocket()).send(($x=[byte[]][char[]](""+($z.remoteendpoint.address-replace"\.","+"|iex))+32),$x.count,0);$z.close()}
AdmBorkBork

1
나는 당신이 이것을 152로 쓰러 뜨릴 수 있다고 생각합니다-새로운 객체를 드롭하고 직접 캐스트하고 바이트 배열 변환을 건너 뛰고 다르게 문자열 캐스트를 수행하고 $ x를 전혀 저장하지 않고 나머지 매개 변수를 send ()에 드롭하십시오. 는 ($t=[net.sockets.tcplistener]$args[0]).start();for(){($z=$t.acceptsocket()).send([char[]]"$($z.remoteendpoint.address-replace"\.","+"|iex)");$z.close()}netcat 연결로만 빠르게 테스트했지만 로컬 호스트에서 연결하는 것과 동일하게 작동합니다.
TessellatingHeckler

4

8086 머신 코드 (16 비트 DOS), 163156148148148142 바이트

00000000  31 c0 bb 0a 00 31 c9 be  81 00 bf 80 00 8a 0d 01  |1....1..........|
00000010  cf 46 8a 0c 80 e9 30 f7  e3 00 c8 39 fe 72 f2 89  |.F....0....9.r..|
00000020  c3 89 c1 b8 01 10 ba ff  ff 31 f6 31 ff cd 61 53  |.........1.1..aS|
00000030  b8 00 12 bf 80 00 b9 01  00 ba ff ff cd 61 b8 00  |.............a..|
00000040  14 cd 61 31 c0 bb 0a 00  83 c7 06 8d 4d 04 26 02  |..a1........M.&.|
00000050  05 80 d4 00 47 39 cf 72  f5 bf 84 00 b9 80 00 bb  |....G9.r........|
00000060  0a 00 4f 31 d2 f7 f3 80  c2 30 88 15 39 cf 77 f2  |..O1.....0..9.w.|
00000070  1e 07 b8 0e 13 5b bf 80  00 b9 04 00 ba ff ff cd  |.....[..........|
00000080  61 b8 00 11 ba 01 00 cd  61 b8 00 4c cd 21        |a.......a..L.!|
0000008e

동등한 어셈블리 코드 :

org 0x100
tcp equ 0x61    ; NTCPDRV interrupt

    xor ax,ax
    mov bx,10
    xor cx,cx
    mov si,0x81     ; [ds:81]-[ds:FF] = command line args
    mov di,0x80     ; [ds:80] = strlen(args)
    mov cl,[di]
    add di,cx

@@: inc si
    mov cl,[si]     ; get character
    sub cl,'0'      ; convert char to int
    mul bx          ; ax *= 10
    add al,cl
    cmp si,di
    jb @b
    ; now ax = port number

    mov bx,ax       ; source port (leaving this 0 doesn't work?)
    mov cx,ax       ; dest port
    mov ax,0x1001   ; open TCP socket for listening
    mov dx,-1       ; infinite timeout
    xor si,si       ; any dest IP
    xor di,di
    int tcp
    ; ^ I think this call should block until a connection is established, but apparently it doesn't.

    push bx         ; bx = socket handle, save it for later

    mov ax,0x1200   ; read from socket
    mov di,0x80     ; es:di = buffer (just reuse argument area to save space)
    mov cx,1        ; one byte
    mov dx,-1
    int tcp         ; this will block until a client connects and sends one byte

    mov ax,0x1400   ; get TCP session status, bx=handle
    int tcp
    ; now es:di points to a struct containing the source/dest IP addresses and ports
    ; the docs say it's two dwords for each IP address, then two bytes for "ip_prot" and "active" (whatever that means)
    ; ...but actually each IP address is followed by the port number (one word)

    xor ax,ax
    mov bx,10
    add di,6        ; [es:di+6] = client IP
    lea cx,[di+4]
@@: add al,[es:di]  ; add all bytes together
    adc ah,0
    inc di
    cmp di,cx
    jb @b
    ; now ax contains the IP address sum

    mov di,0x84     ; recycle arguments area again
    mov cx,0x80
    mov bx,10
@@: dec di
    xor dx,dx
    div bx          ; dl = ax mod 10
    add dl,'0'      ; convert int to char
    mov [di],dl
    cmp di,cx
    ja @b
    ; now [ds:80]-[ds:83] contains an ascii representation of the IP address sum

    push ds
    pop es
    mov ax,0x130e   ; send data with newline, wait for ack
    pop bx          ; socket handle
    mov di,0x80     ; es:di = data
    mov cx,4        ; sizeof data
    mov dx,-1
    int tcp

    mov ax,0x1100   ; close TCP socket
    mov dx,1
    int tcp

    mov ax,0x4c00
    int 0x21

이것은 ntcpdrv에로드 된 것으로 가정합니다 INT 0x61(및에 적합한 패킷 드라이버 0x60). 로 컴파일하십시오 fasm tcpserv.asm.

그래도 몇 가지 문제가 있습니다.

  • 인수가 유효한 포트 번호인지 또는 심지어 숫자인지 여부는 확인하지 않습니다.
  • 클라이언트가 연결되었는지 여부를 알 수있는 다른 방법을 찾지 못하는 것처럼 클라이언트는 적어도 1 바이트를 보내야합니다.
  • 한 번만 작동하고 두 번째 시도에 매달립니다. 재부팅 후 다시 작동합니다.
  • 반환 된 값은 0으로 채워집니다.
  • 이것은 내 첫 번째 코드 골프 항목이며 첫 번째 8086 asm 프로그램입니다. 나는 이것을 더 향상시킬 수있는 방법이 있다고 확신합니다.

1
148 바이트에 대한 컴파일 된 출력의 16 진 덤프를 게시 할 수 있습니다
cat

허용 되나요? 그것은이 항목을 좀 더 경쟁력이있을 것입니다 ...
user5434231

1
좋아, 항목을 기계 코드로 변경했습니다. 또한 xor r,r대신을 사용하여 몇 바이트를 더 줄 였습니다 mov r,0.
user5434231

1
나는 개행이있는 도스 머신에 그것을 썼다 CR LF. 그래서 나는 그와 함께 갔다. 어쨌든 이제는 asm 크기를 계산하는 것이 의미가 없으며 약간 정리하고 주석을 추가 할 수도 있습니다.
user5434231

1
그것은 여기에서도 일어날 것으로 예상되며 작동합니다. int 0x61에서 임의의 로컬 포트를 반환합니다 ax. 그러나 또한 청취 IP를 가비지 번호 ( 4.2.0.0iirc) 로 변경합니다.
user5434231

3

하스켈, 216 바이트

"네트워크 단순"패키지 사용 ( cabal install network-simple). -XOverloadedStrings -XNoMonomorphismRestriction작동하려면 몇 가지 언어 확장 ( )이 필요합니다.

import Network.Simple.TCP(serve)
import Network.Socket
import Data.Bits
main=getLine>>= \n->serve"*"n p
p(s,(SockAddrInet _ h))=()<$(send s$(show$sum$w h 24)++"\n")
m=255
w h 0=[h.&.m]
w h n=h`shiftR`n.&.m:(w h$n-8)

w포트 번호를 인수로 지정할 수 있도록 목록 대신 직접 합계를 반환 하도록 함수를 변경하고 프로그램이 아닌 함수를 사용하는 등 몇 가지 단순화가 가능 합니다. 그래도 이것이 크기를 크게 줄일 것이라고는 생각하지 않습니다. 아마도 20 바이트?


좋은! 당신은 여전히 이름을 변경하여 떨어져 몇 바이트를 면도 할 수 있습니다 확신 w#, 이렇게 w h n하게 h#n사용 당 2 바이트의 절약.
Actorclavilis

3

이하선염, 114 115 바이트

골프 :

R P F{S J=0,I="|TCP|1" O I:(:P) U I R K F K=1:1:4{S J=J+$P(##class(%SYSTEM.TCPDevice).PeerAddr(),".",K)} W J,! C I}

언 골프 드 :

R P             ; Read Port # from STDIN ;
  F{            ; Loop over everything;
  S J=0,        ; Initial IP segment total
  I="|TCP|1"    ; TCP device
  O I:(:P)      ; Open the TCP device, port from input {and sticking a tongue out! :-) }
  U I           ; Use the TCP device
  R K           ; Read from STDIN (anything)
  F K=1:1:4{    ; Iterate 1->4 in variable K
    S J=J+      ; Accumulate the following segments of the IP in var. J
    $P(##class(%SYSTEM.TCPDevice).PeerAddr(),".",K) ; Grab each piece of IPv4.
            }   ; close the loop.
  W J,!         ; Write the total w/newline out the TCP port 
  C I           ; close the TCP port to send.
}               ; end final loop

이것은 Mumps의 InterSystems Caché 버전입니다. ##class(%SYSTEM.TCPDevice).PeerAddr() (전체 프로그램의 거의 1/3이므로) TCP 주소를 더 짧은 버전으로 얻을 수있는 버전이 있다면 이미 게시 된 다른 언어에 비해 더 나은 기회를 가질 수 있습니다 ... ;-)

편집 : @TimmyD 덕분에-하드 코딩 대신 STDIN 또는 인수에서 포트를 읽지 못했습니다. 편집; 프로그램에 1 바이트를 추가했습니다.


@TimmyD-아, 맞습니다. 요구 사항을 읽었을 때 그것을 놓쳤다. posthaste를 편집합니다.
zmerch

3

C, 535 바이트

글쎄, 누군가가 이것을해야했습니다.

한 줄 바꿈을 추가하여 게시 된 코드에 실제로 536자가 있습니다.

#include <stdio.h>
#include <netdb.h>
#include <netinet/in.h>
#include <string.h>
int main(int c,char**v){int f,l;char b[99];struct sockaddr_in d,e;f=socket(AF_INET,SOCK_STREAM,0);bzero(&d,sizeof(d));d.sin_family=AF_INET;d.sin_addr.s_addr=INADDR_ANY;d.sin_port=htons(atoi(v[1]));bind(f,&d, sizeof(d));listen(f,5);l=sizeof(e);
f=accept(f,&e,&l);bzero(b,99);int p,q,r,s;char g[INET_ADDRSTRLEN];inet_ntop(AF_INET,&(e.sin_addr),g,INET_ADDRSTRLEN);sscanf(g,"%d.%d.%d.%d",&p,&q,&r,&s);sprintf(b,"%d\n",p+q+r+s);write(f,b,strlen(b));return 0;}

와 컴파일 gcc [file_name] -o server

와 실행 ./server [port]

~와 연결하다 telnet localhost [port]


3
좋은 대답입니다! 앞에서 언급했듯이 AF_INET 및 SOCK_STREAM과 같은 일부 상수에 대한 실제 값을 사용하여 몇 바이트를 절약 할 수 있습니다.
Hannes Karppila

2

자바, 210 바이트

골프 :

p->{java.net.ServerSocket x=new java.net.ServerSocket(p);for(;;){try(java.net.Socket s=x.accept()){byte[]b=s.getInetAddress().getAddress();s.getOutputStream().write((0+b[0]+b[1]+b[2]+b[3]+"\n").getBytes());}}};

넓히는:

@FunctionalInterface interface Consumer { // Define an interface that allows a function that throws an exception.
  void accept(int port) throws Exception;
}

Consumer consumer = (port) -> {
  java.net.ServerSocket serverSocket = new java.net.ServerSocket(port);
    for (;;) {
      try (java.net.Socket socket = serverSocket.accept()) {
        byte[] bytes = socket.getInetAddress().getAddress();
        socket.getOutputStream().write((0 + b[0] + b[1] + b[2] + b[3] + "\n").getBytes());
      }
    }
}

이것은 내가 다른 Java 답변에서 제공 한 모든 팁과 전체 프로그램 대신 함수로 작성하여 프로그램과 비교하여 약 70 바이트를 얻었습니다.


2

하스켈, 326 바이트

import Data.Bits
import Network.Socket
import System.IO
f n=withSocketsDo$do
 s<-socket AF_INET Stream defaultProtocol
 bind s$SockAddrInet n iNADDR_ANY
 listen s 1
 g s
g s=do
 (z,SockAddrInet _ a)<-accept s
 h<-socketToHandle z WriteMode
 hPutStrLn h$show$b a
 hClose h
 g s
b 0=0
b x=x.&.0xFF+b(x`shiftR`8)

슬프게도 Network.Socket원격 IP 주소에 액세스하는 데 문자열이 아닌 정수 로 사용해야 했습니다. 난 그냥 할 수 있다면 문자 수십 저장 한 것이 s <- listenOn (PortNumber n)아니라 명시 적으로 호출 할 필요없이 socket, bind그리고 listen개별적으로. 그러나 슬프게도 IP 주소 정수가 아닌 Network.accept호스트 문자열을 제공 하므로 친구와 의지해야했습니다 .Network.Socket.accept

이 함수 f는 포트 번호를 인수로 사용 s하여 해당 포트에서 수신 대기 하는 서버 소켓 ( )을 만듭니다 . 그런 다음 g서버 소켓으로 함수를 호출합니다 . g연결을 수락하고 영원히 반복합니다. 이 함수 b는 실제 IPv4 주소를 사용하여 숫자의 합계를 계산합니다.

누군가가 나보다 더 잘 할 수 있다고 확신합니다. 나는 Haskell에 얼마나 쉬운 소켓 소켓이 있는지를 보여주고 싶었지만 IP 주소에 액세스해야하기 때문에 비참하게 실패했습니다. 보통 쉽지 않습니다.


"network-simple"패키지는 SockAddr를 사용자가 제공하는 기능으로 전달하는 훨씬 더 멋진 인터페이스를 제공하여 작업을보다 쉽게 ​​만듭니다. 내가 게시하려는 솔루션을 참조하십시오 ...
Jules

몇 가지 단순화가 명백합니다. (1) withSocketsDoWindows에서만 필요 하다고 생각 하므로 Linux에서 실행하는 경우 무시할 수 있습니다. (2) 0xFF는 255보다 긴 문자입니다. (3) 소켓을 핸들로 변환하고 일반 IO를 사용하는 것이을 사용하는 것보다 훨씬 오래 걸립니다 Network.Socket.send. 예, send더 이상 사용되지 않지만 그 이유는이 시나리오 (ASCII 이외의 텍스트 또는 이진 데이터에만 관련됨)와 관련이 없으므로 사용하는 것이 합리적입니다.
Jules

Network.accept gives me a host string, not an IP address integer당신은 단지에있는 IP 문자열을 분할 할 수 없습니다 ".", map분할 문자열을 통해 하스켈의 문자열에 번호 기능을하고 그 결과를 요약하면?
고양이

2

루아, 169 162 160 153 151 148 138 129 바이트

골프 버전

m=require"socket".bind(0,...)::l::c=m:accept()f=0 for n in c:getpeername():gmatch"%d+"do f=f+n end c:send(f.."\n")c:close()goto l

Luasocket을 설치하고 레이블을 지원하는 인터프리터가 필요합니다. Luajit으로 테스트했으며 코드가 Lua 5.1에서 작동하지 않는지도 확인할 수 있습니다.

언 골프 버전

m=require"socket".bind(0,...)
::l::
c=m:accept()

f=0
for n in c:getpeername():gmatch"%d+" do
    f=f+n
end
c:send(f.."\n")

c:close()
goto l

편집 1 :

i=({c:getpeername()})[1]그냥 변경i=c:getpeername()

편집 2 :

require 문에서 중괄호를 제거했습니다.

편집 3 :

vararg 주위의 괄호를 제거하고 바이트 수를 약간 줄였습니다.

편집 4 :

"% d +"주위의 괄호를 2 바이트 씩 제거했습니다.

편집 5 :

불필요한 변수를 제거했습니다 i.

편집 6 :

ip를 "127.0.0.1"에서 0으로 변경했습니다. #lua의 xyzzy에 감사합니다.

편집 7 :

문자열이 자동으로 숫자로 캐스트되므로 tonumber에 대한 함수 호출을 제거했습니다 (제안 해 주셔서 Trebuchette에게 감사드립니다, 나는 이것을 몰랐습니다)


1
궁금한 경우 Lua 5.2 이상 만 레이블 지원
Trebuchette

1
또한 Lua는 +연산자를 사용하여 문자열을 숫자로 자동 캐스트하므로을 꺼낼 수 있습니다 tonumber.
Trebuchette

2

하스켈, 185 (+ 19 = 204)? 바이트

import Network.Simple.TCP(serve)
import Network.Socket
import Data.List.Split
main=getLine>>=flip(serve"*4")(\(a,b)->()<$(send a$(++"\n")$show$sum.map read.take 4.sepByOneOf":."$show b)

stdin에서 포트 번호를 한 줄로 취합니다. network-simpleCabal이 필요합니다 .

순수한 함수에 자신을 제한하지 않는 Haskell의 답변과 마찬가지로 imports너무 많은 바이트를 차지합니다. 후행 줄 바꿈은 9 바이트의 가치가 있습니다 ...

@Jules의 답변과 다소 비슷하지만 바이트 작업 대신 문자열 조작을 사용합니다. 나는 스톨 사용 된 -XOverloadedStrings아마 여분의 19 바이트 가치가있는뿐만 아니라 확장.


2

C, 243 188 바이트 (또는 아마도 217162 바이트)

V2 : 설명은 아래를 참조하십시오.

188 바이트 :

s;main(g,v)char**v;{short S[8]={2,htons(atoi(v[1]))};char C[g=16];bind(s=socket(2,1,0),&S,g);for(listen(s,8);g=fdopen(accept(s,&C,&g),"w");fclose(g))fprintf(g,"%d\n",C[4]+C[5]+C[6]+C[7]);}

162 바이트 약간의 여유

s;main(g){short S[8]={2,g};char C[g=16];bind(s=socket(2,1,0),&S,g);for(listen(s,8);g=fdopen(accept(s,&C,&g),"w");fclose(g))fprintf(g,"%d\n",C[4]+C[5]+C[6]+C[7]);}

아마 내일 아침에 더 많은 골프가 가능할 것입니다. 업데이트 후에이 게시물을 정리하겠습니다.


V1 :

이 골프는 정말 재미있었습니다.

#include<netdb.h>
s,c,q;main(g,v)char**v;{struct sockaddr_in S={2,htons(atoi(v[1]))},C;bind(s=socket(2,1,0),&S,g=16);for(listen(s,8);c=accept(s,&C,&g);q=fclose(g)){for(g=4;g;q+=C.sin_addr.s_addr>>8*--g&255);fprintf(g=fdopen(c,"w"),"%d\n",q);}}

IPv4에서 작동합니다. 대부분 간단한 구현입니다. 세 가지 주요 구성 요소는

소켓 만들기 :

struct sockaddr_in S = {2, htons (atoi (v [1]))}, C; bind (s = socket (2,1,0), & S, g = 16);

우리는 상수 AF_INET 등의 다양한 명시 적 형식을 사용하며, 이런 식으로 C에서 구조체가 초기화 될 때 지정되지 않은 요소는 0으로 설정된다는 사실을 이용합니다.

고객의 의견을 경청하고 수락 한 다음 연결을 끊습니다.

for (듣기 (들, 8); c = 수락 (들, & C, & g); q = 닫기 (g))

마지막으로 각 클라이언트에 데이터를 보내려면 다음을 수행하십시오.

for (g = 4; g; q + = C.sin_addr.s_addr >> 8 *-g & 255); fprintf (g = fdopen (c, "w"), "% d \ n", q);

IP는 C.sin_addr.s_addr32 비트 정수로 저장 되며 각 옥텟은 4 바이트 중 하나로 표시됩니다. 이러한 바이트를 for 루프와 합한 다음 fprintf를 사용하여 스트림에 인쇄합니다.

나는 짧은 217 바이트 솔루션을 가지고 있지만 포트가 네트워크 바이트 순서로 단항으로 명령 줄 인수로 제공되어야하기 때문에 표준 허점을 위반하지 않는다는 것을 완전히 확신하지는 못합니다. 즉, 포트 12345에서 서버를 실행하려면 다음을 호출해야합니다.

$ ./tcp 1 1 1 ... 1 1 1

1s 의 총 개수 는 14640입니다. 그러나 어쨌든 여기 있습니다.

#include<netdb.h>
s,c,q;main(g){struct sockaddr_in S={2,g},C;bind(s=socket(2,1,0),&S,g=16);for(listen(s,8);c=accept(s,&C,&g);q=fclose(g)){for(g=4;g;q+=C.sin_addr.s_addr>>8*--g&255);fprintf(g=fdopen(c,"w"),"%d\n",q);}}

2

라켓, 265 바이트

#lang racket(define l(tcp-listen(string->number(read-line))))(let e()(define-values(i o)(tcp-accept l))(thread(λ()(define-values(a b)(tcp-addresses o))(write(~a(foldl + 0(map string->number(string-split a".")))o))(newline o)(close-output-port o)))(e)))

언 골프 드 :

#lang racket
(define listener (tcp-listen (string->number (read-line))))
(define (mk-server)
  (let echo-server ()
    (define-values (in out) (tcp-accept listener))
    (thread
     (λ()
       (define-values (a b) (tcp-addresses out))
       (write (number->string (foldl + 0(map string->number(string-split a "."))) out))
       (write "\n" out)
       (close-output-port out)))
    (echo-server)))

2

팩터 155 146 131 206 190 바이트

글쎄, 나는 저수준 소켓 프로그래밍에 대해 많은 것을 배웠다. 내 때문에, 내가 싶어 그 다시 할 생각하지 않는다 THR의 머리가 아파요.

[ utf8 <threaded-server> readln 10 base> >>insecure [ remote-address get host>> "." split [ 10 base> ] map sum 10 >base print flush ] >>handler [ start-server ] in-thread start-server drop ]

오 예, 스레드되고 돌아 오지 않습니다.


10 base>대신 사용할 수 있습니까 string>number?
페더

@ 페더스. 와우, 나는 그것이 존재하는 것을 전혀 몰랐다. 나는 그것이 나의 요인 답변을 많이 단축시킬 수 있다고 생각합니다!
고양이

그리고 10 >base숫자> 문자열도.
페더

1
@ 페더스. 여기 에 대답이 필요합니다 . : D
cat
당사 사이트를 사용함과 동시에 당사의 쿠키 정책개인정보 보호정책을 읽고 이해하였음을 인정하는 것으로 간주합니다.
Licensed under cc by-sa 3.0 with attribution required.