質問をすることでしか得られない、回答やアドバイスがある。

15分調べてもわからないことは、質問しよう!

新規登録して質問してみよう
ただいま回答率
85.50%
C

C言語は、1972年にAT&Tベル研究所の、デニス・リッチーが主体となって作成したプログラミング言語です。 B言語の後継言語として開発されたことからC言語と命名。そのため、表記法などはB言語やALGOLに近いとされています。 Cの拡張版であるC++言語とともに、現在世界中でもっとも普及されているプログラミング言語です。

C#

C#はマルチパラダイムプログラミング言語の1つで、命令形・宣言型・関数型・ジェネリック型・コンポーネント指向・オブジェクティブ指向のプログラミング開発すべてに対応しています。

Q&A

解決済

2回答

12913閲覧

C言語とC#間でSocket通信をさせたい

aridai1221

総合スコア45

C

C言語は、1972年にAT&Tベル研究所の、デニス・リッチーが主体となって作成したプログラミング言語です。 B言語の後継言語として開発されたことからC言語と命名。そのため、表記法などはB言語やALGOLに近いとされています。 Cの拡張版であるC++言語とともに、現在世界中でもっとも普及されているプログラミング言語です。

C#

C#はマルチパラダイムプログラミング言語の1つで、命令形・宣言型・関数型・ジェネリック型・コンポーネント指向・オブジェクティブ指向のプログラミング開発すべてに対応しています。

0グッド

0クリップ

投稿2016/10/28 05:45

###前提・実現したいこと
C言語とC#でローカルな(同一PC内での)ソケット通信を行いたいです。
C言語側ではWinSocketを利用してサーバーを立て
C#側ではSystem.Net.Sockets.TcpClientを利用してクライアントとして
C言語側から送られてくるint型のデータを取得したいです。

###発生している問題・エラーメッセージ

対象のコンピューターによって拒否されたため、接続できませんでした。

###該当のソースコード

C++

1#define _WINSOCK_DEPRECATED_NO_WARNINGS 2 3#include <stdio.h> 4#include <stdlib.h> 5#include <winsock2.h> 6 7#pragma comment(lib, "ws2_32.lib") 8 9WSADATA wsaData; 10SOCKET sock; 11sockaddr_in addr; 12 13int main() 14{ 15 WSAStartup(MAKEWORD(2, 0), &wsaData); 16 sock = socket(AF_INET, SOCK_DGRAM, 0); 17 addr.sin_family = AF_INET; 18 addr.sin_port = htons(12345); 19 addr.sin_addr.S_un.S_addr = inet_addr("127.0.0.1"); 20 21 while (true) 22 { 23 sendto(sock, (char*)114514, 32, 0, (sockaddr*)&addr, sizeof(addr)); 24 } 25 26 closesocket(sock); 27 WSACleanup(); 28 29 return 0; 30}

C#

1using System; 2using System.Net.Sockets; 3 4class Client 5{ 6 public static void Main() 7 { 8 try 9 { 10 //サーバーに接続 11 Int32 port = 12345; 12 TcpClient client = new TcpClient("127.0.0.1", port); 13 14 NetworkStream stream = client.GetStream(); 15 16 while (true) 17 { 18 int value = stream.ReadByte(); 19 Console.WriteLine(value); 20 } 21 22 client.Close(); 23 } 24 25 catch (Exception e) 26 { 27 Console.WriteLine(e.Message); 28 } 29 30 } 31}

###試したこと
ファイアウォールを無効にしたりしました。

気になる質問をクリップする

クリップした質問は、後からいつでもMYページで確認できます。

またクリップした質問に回答があった際、通知やメールを受け取ることができます。

バッドをするには、ログインかつ

こちらの条件を満たす必要があります。

guest

回答2

0

こんにちは。

C言語での解はhiimさんの回答を御覧ください。

PCならばC++も使えると思います。C++ならBoost.Asioを使えばかなり簡単です。
最近Boost.Asioのtcp::streamを使ってみて個人的にフィーバーしているので、ここを参考にちょろっと作ってみました。(C++が使えない環境でしたらごめんなさい。)

stdafx.h

C++

1// stdafx.h : 標準のシステム インクルード ファイルのインクルード ファイル、または 2// 参照回数が多く、かつあまり変更されない、プロジェクト専用のインクルード ファイル 3// を記述します。 4// 5 6#pragma once 7#include "targetver.h" 8#include <stdio.h> 9#include <tchar.h> 10 11// TODO: プログラムに必要な追加ヘッダーをここで参照してください 12#ifndef _WIN32_WINNT 13#define _WIN32_WINNT 0x0501 14#endif 15#define BOOST_DATE_TIME_NO_LIB 16#define BOOST_REGEX_NO_LIB 17#define BOOST_ASIO_ENABLE_CANCELIO 18#define BOOST_ERROR_CODE_HEADER_ONLY 19#define BOOST_SYSTEM_NO_LIB 20#include <boost/asio.hpp> 21namespace boostA = boost::asio;
server.cpp

C++

1// Server.cpp : コンソール アプリケーションのエントリ ポイントを定義します。 2// 3 4#include "stdafx.h" 5 6int main() 7{ 8 //ポート番号12345で待ち受け 9 boostA::io_service aIoService; 10 boostA::ip::tcp::endpoint aEndpoint(boostA::ip::tcp::v4(), 12345); 11 boostA::ip::tcp::acceptor aAcceptor(aIoService, aEndpoint); 12 13 boostA::ip::tcp::iostream aTcpStream; 14 aAcceptor.accept(*aTcpStream.rdbuf()); 15 16 // int型データを文字列へ変換して送信 17 aTcpStream << 5678 << "\n"; 18 19 return 0; 20}

#include <boost/asio.hpp>の前の多数の#defineはboost::asioをヘッダ・オンリで使うための指示です。ここに載ってます。
プロジェクトには追加のインクルードにboostを解凍したフォルダを指定するだけで使えます。

C#側クライアント修正版

C#

1using System; 2using System.Collections.Generic; 3using System.Linq; 4using System.Text; 5using System.Threading.Tasks; 6using System.Net.Sockets; 7using System.IO; 8 9class Client 10{ 11 public static void Main() 12 { 13 try 14 { 15 //サーバーに接続 16 Int32 port = 12345; 17 using (TcpClient client = new TcpClient("127.0.0.1", port)) 18 using (NetworkStream ns = client.GetStream()) 19 using (StreamReader sr = new StreamReader(ns)) 20 { 21 // データ受信と表示 22 while (sr.Peek() >= 0) 23 { 24 string value=sr.ReadLine(); 25 Console.WriteLine(Int32.Parse(value)); 26 } 27 } 28 } 29 catch (Exception e) 30 { 31 Console.WriteLine(e.Message); 32 } 33 } 34}

サーバを先に起動しておいて、クライアントを起動すれば動作します。
しかし、久しぶりにC#のI/Oを使ったけど、C++のiostreamに慣れるとちょっと不便に感じますね。
int型をバイナリーで交換することもできる筈ですが、面倒なので文字列で交換してます。

投稿2016/10/28 08:03

編集2016/10/28 08:04
Chironian

総合スコア23272

バッドをするには、ログインかつ

こちらの条件を満たす必要があります。

0

ベストアンサー

まずC言語の方がサーバーとして機能していません。
ソケットを作ってbindしてlistenしないといけません。

こんな感じに

追記

C言語側ではWinSocketを利用してサーバーを立て
C#側ではSystem.Net.Sockets.TcpClientを利用してクライアントとして

「C言語側から送られてくるint型のデータを取得したいです。」

サーバー側からクライアントに送るという事はクライアントから接続されたソケットを使ってデータを送ります。

追記

参考に貼ったURLにあるサーバーのソースの

c

1// ソケットの作成 2 sock0 = socket(AF_INET, SOCK_STREAM, 0);

でlisten用のソケットを作って(接続要求を待つ用のもの)

c

1bind(sock0, (struct sockaddr *)&addr, sizeof(addr)); 2 3 // TCPクライアントからの接続要求を待てる状態にする 4 listen(sock0, 5);

bindでsock0にどのアドレス、どのポートとかの紐付けをする
listenして

c

1sock = accept(sock0, (struct sockaddr *)&client, &len);

接続要求があれば接続してきたクライアントと通信するためのソケットを返します。

このsock0とsockは別ものです。(同じものだとサーバー1つに対してクライアントも1つしか接続できないようになってしまうので。。)

という感じです。

投稿2016/10/28 05:50

編集2016/10/28 06:15
hiim

総合スコア1689

バッドをするには、ログインかつ

こちらの条件を満たす必要があります。

aridai1221

2016/10/28 09:20

ありがとうございます。 できました。
guest

あなたの回答

tips

太字

斜体

打ち消し線

見出し

引用テキストの挿入

コードの挿入

リンクの挿入

リストの挿入

番号リストの挿入

表の挿入

水平線の挿入

プレビュー

15分調べてもわからないことは
teratailで質問しよう!

ただいまの回答率
85.50%

質問をまとめることで
思考を整理して素早く解決

テンプレート機能で
簡単に質問をまとめる

質問する

関連した質問