単純なTCPサーバー


104

ポートNで着信TCPトラフィックをリッスンするプログラムまたは関数を作成します。簡単なサービスを提供します。着信接続のIPアドレスフィールドの合計を計算して返します。

プログラムまたは関数は、引数または標準入力から整数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などを使用できますか?
デジタル外傷

91
ゴルフの言語があまり得意ではないのはゴルフの挑戦なので、私はこれが好きです。
isaacg

9
TCPサーバーが明らかに非常に簡単に作成できるプログラムであることに驚くだけでなく、私はそれが楽しみのためにゴルフをしているという事実に徹底的に床を張っています。私は、FizzBu​​zzとの格闘に苦労することに戻ります。
MonkeyZeus

17
@isaacg誰かがMathematicaに組み込まれたTCPサーバーを見つけるまでの時間です
-Downgoat

3
@MonkeyZeus公平を期すため、ここには適切 TCPサーバーは表示されません。あなたもする必要はありません-それは確かに、プロトコルは非常にシンプルであることに役立ちますけれどもD:だけでなく、すべてのTCPの複雑さ(およびアプリケーションプロトコル)を扱う信頼性の高い、スケーラブルなTCPサーバを少し難しくされて作る読んストリームを、何か数え切れないほど多くの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.

Ubuntuではncnetcat-traditional(いいえ、netcat-openbsdは良くありません)およびiproute2ssから取得できます。


22
なぜ深刻な解決策ではないと言うのですか?期待どおりに機能する限り、それが深刻であると見なされるべきではない理由はわかりません。また、現時点ではかなり短いマージンです。
アレックスA.

それに対する最大の懸念は、@ JesseSielaffとの話し合いの中で現れました。IPv6が構成されたシステムでは、ソケット関連の情報が異なってフォーマットされる可能性があることを知りました。テストするようなシステムはありません。CWに変換する方が正しいかどうかを考えています。
マナトワーク

3
私の仕様の理解は、両方ではなくIPv4 または IPv6 をサポートする必要があるということです。したがって、IPv4で機能する限り、IPv6をサポートしていなくてもかまいません。
アレックスA.

1
@AlexA。少なくとも私の質問はそう言っていると思います。明確にする必要がありますか?
ハンネスカルピーラ

@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 Yeah、それはデバッグから残った。
LegionMammal978

また、でを使用するusingと、TcpClientさらに3つの文字が保存され({}fromを使用for)、同じ操作を行うとStreamWriterもう1つ保存されます。
ルアーン

@Luaan私は明示的にする必要があり、それが正常に動作するように。FlushStreamWriter
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実行可能ファイルの作成方法に関する情報は、ブレッドボックスLinux用の本当にティーンジーなELF実行可能ファイルの作成に関するWhirlwindチュートリアル」にあります。

Linux / i386は、socketcall(2)マルチプレックスシステムコールを使用します。これはebx、特定のソケットコール(SYS_*からのマクロ/usr/include/linux/net.h)とecx、元のライブラリコールの引数領域へのポインタを受け取ります。

実行可能ファイルを小さく保つために行われたいくつかのこと:

  • Linuxはエントリがゼロになることを前提としていますが、Linuxはそうではありませんが、ELF標準では必要ありません(唯一の要件は、エントリEDXがファイナライズ機能(ダイナミックリンカによってロードされる実行可能ファイルに有用)を指すことです)またはNULLです。
  • 起動時(通常はシェルによる)に、開いているファイル記述子は0、1、および2のみであると想定します。つまり、リスニングソケットはfd 3で、受け入れられるソケットはfd 4になります。
  • (を含むargv[0])正確に2つの引数があると仮定します。
  • 同じスタック空間はへの呼び出しのために再利用されbind(2)listen(2)そしてaccept(2)
  • phentsizeand phnumフィールドをスキップするには、1バイトが先頭に追加されCMPphentsizeand phnumフィールドを即座に取得する操作になります(ブレッドボックスのソリューションから無秩序なゴルフで123に恥ずかしく盗まれたトリック)。
  • x86文字列操作LODS(アキュムレータへのロードとソースインデックスのインクリメント/デクリメント)およびSTOS(アキュムレータからのストアとデスティネーションインクリメント/デクリメントインデックス)は、短いコードに適しています。
  • XCHG EAX, regと比較してMOV EAX, reg、1バイトです。
  • CDQ/CLTD(sign-extend EAXinto EDX:EAX)は、EDXレジスタをゼロにする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
今は127バイトをカウントしていますが'\n'、リテラルの改行を含むテンプレート文字列と交換することで、126バイトに減らすことができます。
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ベースのアプローチも同様に長くなります)。
ドナルドフェローズ

ああ、Tcl / Tcl-DP ...驚くほどたくさんのツール。(90年代に教授が示したのは、サーバー用に4(短い)行、クライアント用に5(iirc)の行を持つ複数の人の間で共有されるネットワーク分散Excel(グリッド付き、数式評価を含む!)を作成できることです。 ..
オリビエデュラック

proc s {c a p}本当にすべての空白が必要ですか?

12

グルービー13312593、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 thx!更新しました。
ウィルLp

9

Pythonの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 / Linux(および、私は他のほとんどのユニックス)で動作します。これは、「」を「0.0.0.0」に自動的に展開しますが、Windowsについてはわかりません。


2
数バイト節約できます。まず、内のスペースimport *とは, SOCK_STREAM不要です。また、送信行はとしてより効率的に記述できますc.send(b"%d\n"%eval(a[0].replace(".","+")))
ハンネスカルピーラ

2
@HannesKarppilaああ、ありがとう。スペースを忘れてしまいましたが、評価ハックはかなりクールです。
sammko

2
AF_INETとSOCK_STREAMは単なる定数です。AF_INETは2、SOCK_STREAMは1です。また、前述のように、SOCK_STREAMは不要です。そのため、代わりにを使用して短縮できますs=socket(2)
スカイラー

1
socket()だけを実行して、別のバイトを保存することはできませんか?
FOON

1
Python 2を使用して10文字を保存できます。その後、にint(input())なりinput()、送信部分がc.send(`eval(a[0].replace(".","+"))`)
Blender

9

Java、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=、kをすべてのcのものに置き換えInteger.toString(k)ます。数バイト節約します。
ジャイアントツリー

1
Javaバイトは192.168.2.1または同様のアドレスの戻り値を127を超えるバイトでかなり混乱させます
。– AlexR

1
変更interfaceclassいくつかのより多くのバイトを得る必要があります
ortis

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")
オーティス

3
ではないtry(Socket a=...){}より短いですかa.close();?Java 7が必要ですが、バイトを増やすことができます。
オリビエグレゴワール

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アドレスではなくlocalhostを暗黙的に使用することでさらに30バイトを節約し、当初指定された継続的な使用を考慮して修正

両方の基礎となる.NETであるため、C#の回答に本当に似ています。PowerShellの返される機能を利用してC#の回答よりも数バイトを節約します(かっこで宣言/割り当てを囲み、すぐに。メソッドを呼び出します)が、合計を定式化する必要があるため、非常に多くを失います。クラス名/呼び出しがわずかに短いという事実が、この答えがC#に勝っている理由です。

説明

最初にNew-Aliasnalエイリアスを使用して)を作成して、New-Object後で再入力するときに保存します。最初の行の残りは、TCPリスナーを設定しています。$args[0]としてSystem.Net.Sockets.TcpListener保存された新しいを作成するための入力としてコマンドラインを渡し$lます。そのオブジェクトは括弧でカプセル化され、すぐに呼び出さ.Start()れて、ソケットをアクティブに開きます。

無限forループに入ると、リスナー$lをブロックに設定し、それによりAcceptTcpClient()接続を待機します。その接続への参照(作成された$c後)はに保存され、括弧でカプセル化され、すぐに呼び出さGetStream()れてデータストリームを取得します。そのデータストリームは新しいSystem.IO.StreamWriterコンストラクタに渡されるため、$w操作できます。そのコンストラクタ自体は括弧でカプセル化され、すぐに呼び出されWrite(...)ます。

Write(...)呼び出し内で、クライアントハンドル$cを取得し、クライアントのRemoteEndPointプロパティを取得します。これは、リモートIPアドレスを取得する唯一の方法です(これまでに見つけた方法です)。次に[System.Net.IPEndPoint]、それをオブジェクトとして再キャストして、正しくフォーマットされ、括弧でカプセル化され、.Addressプロパティのみをプルする必要があります。次に-replace、正符号の付いたリテラルのピリオドをInvoke-Expression(に似たeval)にパイプして合計を取得します。

IO書き込み後、.Dispose()データストリームがクライアントにフラッシュされて閉じられるように呼び出す必要があります。TCPサーバーは警告なしにクライアント接続をドロップするため、使用するクライアントによっては、この時点でしばらくハングすることがあります。その後、for接続を適切に閉じずにループを継続します。これはまた、メモリとシステムハンドルが狂ったようにリークすることを意味しますが、それは気にしませんよね?ただし、サーバーの実行が完了したら、タスクマネージャーを使用してプロセスを強制終了する必要があります。:D

また、IPv4のみ。合計barfsは見事にIPv6アドレスを処理しようとします。これ:iex、解析するための有効な代数演算子ではないためです。


2
「メモリリークが発生すると、システムが狂ったように扱う」、あなたは何をしなければならないのfree()後に?delete[]、 多分?:P

8
@tacうん、全体のスルーがあります.close()し、.dispose()フィット感を持つようにコードレビューに人々を引き起こす私たちがここで呼び出していない方法。
-AdmBorkBork

ああ、PS GCではありませんか?または、GCはスコープ分析ではなくリカウントを行いますか?

@tacはい、基礎となる.NETシステムのおかげで、PowerShellにはガベージコレクションがあります。しかし、このスクリプトを呼び出すか、活用しているかに応じて、次のようなバグに遭遇することができ、この1のパイプラインでメモリリーク。上記のコードもスレッドセーフではないため、ソケットを明示的に閉じていないため、GCの問題が発生する可能性があります。
AdmBorkBork

1
テストでは、おそらく修正する気がないファイアウォールの問題が原因で、これを機能させることができませんでしたので、確信できませんが.....すべての型キャストではないにしても、ほとんどのシステムから「システム」をドロップできると思いますつまり、[Net.ipaddress]::Any作品があります。
マット

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

クライアントとしてのChrome スクリーンショット

編集2:クライアントとしてのwget

$ wget -qO- localhost:8080
128

「プログラムまたは関数は引数または標準入力から整数Nを読み取る」というルールを知っていますが、この場合のプログラムがphpであれば問題ありませんか または、PHPのビルトインサーバーを使用して抜け穴と考えていますか?
ミカエル

プログラミングパズルとコードゴルフへようこそ!161バイトのソリューションは見栄えがします。あなたが言及した56バイトのソリューションは下のものtest2.phpですか?もしそうなら、この種のビルトインをこの課題に受け入れられると考えるかどうかをOPに尋ねる必要があると思います。しかし、抜け穴ではありません。
アレックスA.

組み込みのTCPサーバーを使用してもかまいませんが、この場合は組み込みのHTTPサーバーについて説明します。したがって、56バイトのソリューション1)は、クライアントが接続して送信するだけでは何もしません。2)クライアントが「foo」などを送信した場合、test2.phpを実行せずに「[Wed Mar 30 10:15:02 2016] 127.0.0.1:47974 Invalid request(Malformed HTTP request)」のみを返信します。3)クライアントが有効なHTTP要求を送信する場合、実際に必要な応答の前にHTTP応答ヘッダーの完全なセットを送信します。
マナトワーク

@アレックスA.はい、56バイトのソリューションはtest2.phpの下にあります:)
ミカエル

@manatworkあなたは正しいですが、クライアントはこのタスクで明確に指定されていないと思っていました。ブラウザとして、またはクライアントとして「wget -qO- localhost:8080」のようなもっと単純なものを使用しても大丈夫ですか?
ミカエル

7

行く359 311

これはGoでの私の最初のプログラムです。1つのことを発見できました。これは間違いなく良いゴルフ言語ではありません。

(ゴルフのほとんどを行った@steveに称賛を!)

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サーバーを作るための素晴らしい言語です!
ヌメリ

1
奇数、427ではなく192.168.0.67から接続すると360の結果が得
スティーブ

3
文字列とstrconvパッケージに名前を付けて、数バイト節約できます。例えば、後者がちょうどに"strings"なるs "strings"ようにstrings.Splitなりますs.Split
スティーブ

1
さらにいくつかのバイトが削り取らpastebin.com/HY84sazEを -もう少し見始め、今「golfed」
スティーブ・

2
import(."pkgname")すべての関数を使用する場合は、現在のネームスペースにインポートされるため、プレフィックスを削除できます。例えば。パッケージから正規表現の代わりにアドレスを解析import ."fmt"; Println("foo") するために使用するSscanfと、fmtさらに数バイト節約されFprintln、インポートの代わりに合計を返すという素晴らしいボーナスが得られstrconvます。
クリストファーサル-ストーガード

7

Common Lisp、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
Common Lithpのイェーイ!

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:(最初は2番目のコマンドライン引数を取り"-"伝えるためであるqと解釈していないNスクリプト/ファイルとして)と(ポートを開く"p "ことで)。
    • 注:呼び出しq -p NはポートをN自動的に設定しますが、質問Nは実行可能ファイル自体ではなくプログラムへの引数であることを示唆しているように思われるので、長い道のりを歩んできました。
  • .z.pg着信要求を処理する関数内で、.z.aIPアドレスを32ビット整数として保持します。
    • "i"$0x0 vsそれを整数の「構成要素」に分割sumし、合計します。
    • 最後にstring、数値結果を追加"\n"し、クライアントに返すために追加します。
  • .z.ph HTTP GETリクエスト用の別の関数であり、文字列出力を有効なHTTP応答に変換する追加の処理があります。

デモ-サーバー:

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の基本的なものです。&1(2番目の引数)、<|(F#パイピング、$Haskellの(+)ような)およびbiop:LSのスタイルポイントは、Haskellの演算子セクションのようなものです:カリー化されたバイナリ関数(オペランドを追加)。また、少し汚い:/リテラル文字列が与えられた場合、分割します。


5

Perl、141 132 + 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/./+/
マナトワーク

ああ、誤読..それに応じて修正し、あなたの良いy /提案を取り入れます。
スティーブ

1
while(1){…}user130144のすばらしいヒントに{…;redo}よると。そして、呼び出しを除いて、他のすべての括弧は不要です。->send()
マナトワーク

4

Python 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おっと、その改行を忘れてしまいました。テンプレート文字列のおかげで1バイトしか追加しません。IPファミリについて:.listen()最初はデフォルトでIPv4が使用されていましたが、バグまたは設計により、これが変更されたようです。ホストマシンでIPv6が無効になっている場合、新しいバージョンのノードでも送信は引き続き適切に機能します。
Mwr247

4

Go、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に感謝します!

TessellatingHecklerのおかげで、40バイト節約できました


@TimmyDああ、私はそれが必要だったことを逃しました...今修正されました
Nacht

プログラムが入力を許可される方法の1つは、stdinからのものです。この特定の質問ではそれが許可されているとは指定されていないと思いますが、PowerShellで考慮すべき一般的なコードゴルフのことです。残念ながら、bashとは異なり、何も指定されていない場合はstdinでの入力を待機しません。
ヨット

けっこうだ。再び修正
Nacht

さて、今いくつかのゴルフのために($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()}
-192

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)、163 156 148 148 142バイト

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バイトを送信する必要があります。
  • 一度だけ動作し、2回目の試行でハングします。再起動後に再び機能します。
  • 返される値の左側にはゼロが埋め込まれます。
  • これは私の最初のコードゴルフエントリであり、また私の最初の8086 asmプログラムです。これをさらに改善する方法があると確信しています。

1
コンパイルされた出力のhexdumpを148バイトだけ投稿できます

それは許されますか?これにより、このエントリはもう少し競争力のあるものになります
...-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

Haskell、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バイトの節約のために。
アクタークラビリス

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

これはInterSystemsCachéバージョンのMumpsです。TCP ##class(%SYSTEM.TCPDevice).PeerAddr() プログラムを取得できるバージョンが(プログラム全体のほぼ3分の1であるため)ある場合は、すでに投稿されている他の言語のいくつかに対してより良いチャンスがあります。 ... ;-)

編集:@TimmyDのおかげで-ハードコーディングされる代わりに、STDINまたは引数からのポートの読み取りを見逃しました。編集済み; プログラムに1バイトを追加しました。


@TimmyD-ああ、あなたは正しい。要件を読んでそれを逃した。ポストヘイストを編集します。
zmerch 16

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などの定数の実際の値を使用して、数バイトを節約できます。
ハンネスカルピーラ16

2

Java、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

Haskell、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たりbindlisten個別に呼び出したりするのではなく、単にできれば数十文字を節約できたでしょう。しかし、悲しいことに、IPアドレス整数ではなくNetwork.acceptホスト文字列を提供してくれるので、友人や友人に頼らなければなりませんでした。Network.Socket.accept

この関数fは引数としてポート番号を取り、sそのポートでリッスンするサーバーソケット()を作成します。次にg、サーバーソケットで関数を呼び出します。g接続を受け入れて、永久にループします。この関数bは、実際のIPv4アドレスを取得し、その数字の合計を計算します。

どこか誰かがこれを私より上手にできると確信しています。Haskellの簡単なソケットがどれほどひどいものかを見せたかったのですが、IPアドレスにアクセスする必要があり、通常は簡単ではないため、悲惨なことに失敗しました。


「ネットワークシンプル」パッケージは、SockAddrを指定した関数に渡す、より優れたインターフェイスを提供します。私が投稿しようとしている私のソリューションを参照してください
ジュール

いくつかの単純化が明らかです。(1)withSocketsDoWindowsでのみ必要であると考えているため、Linuxで実行する場合は無視できます。(2)0xFFは255より長い文字です。(3)ソケットをハンドルに変換し、通常のIOを使用すると、を使用するよりもはるかに長くなりNetwork.Socket.sendます。はい、send廃止されましたが、理由はこのシナリオに関係ないため(非ASCIIテキストまたはバイナリデータにのみ関連するため)、使用するのが妥当と思われます。
ジュール

Network.accept gives me a host string, not an IP address integerあなただけのIP文字列を分割することはできません"."map分割された文字列の上にHaskellの文字列から数値への機能と結果を合計しますか?

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:

可変引数の周りの中括弧を削除し、バイト数を少し減らしました。

編集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
トレブシェット

2

Haskell、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のポート番号を1行として取ります。network-simpleCabalからの要求。

Haskellの回答では、純粋な関数に制限されないので、いつものように、importsバイトが多すぎます。末尾の改行も9バイトの価値があります...

@Julesの答えに多少似ていますが、バイト操作の代わりに文字列操作を使用します。私が盗んだ使用-XOverloadedStrings、おそらく余分な19バイトの価値がある、同様の拡張子を。


2

C、243 188バイト(またはおそらく217 162バイト)

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で機能します。ほとんどは簡単な実装です。3つの主要なコンポーネントは

ソケットの作成:

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

AF_INETなどのさまざまな明示的な形式を使用し、この方法でCで構造体を初期化すると、指定されていない要素がゼロに設定されるという事実を利用します。

クライアントをリッスンし、受け入れ、接続を閉じます。

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);

IPはに保存されます C.sin_addr.s_addr、各オクテットが4バイトのいずれかで表される32ビット整数としてます。これらのバイトをforループで合計し、fprintfを使用してストリームに出力します。

私は短い217バイトのソリューションを持っていますが、ポートがコマンドライン引数としてネットワークバイト順で単項で与えられる必要があるため、標準の抜け穴に違反していないことは完全にはわかりません。つまり、ポート12345でサーバーを実行するには、呼び出す必要があります

$ ./tcp 1 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か?
フェデ。

@fedes。うわー、私はそれが存在することを知りませんでした。これにより、ファクターの回答の多くを短縮できると思います!

また10 >base、number> stringについても。
フェデ。

1
@fedes。これらはここで答えに値する:D
cat
弊社のサイトを使用することにより、あなたは弊社のクッキーポリシーおよびプライバシーポリシーを読み、理解したものとみなされます。
Licensed under cc by-sa 3.0 with attribution required.