こんにちは、Shoutcast ストリーム サイトに http 要求を送信して応答を読み込もうとしました。この 2 つのソースは 1 つはメイン (私は wpf でテスト済み) で、もう 1 つはソケットの小さなヘルパーです...まあlocalhost や他のサイトではすべて動作しますが、「209.9.238.6:6042」にリクエストを送信しようとすると、応答のヘッダーが完全ではなく切り捨てられます。
私は多くのテストを行いましたが、Thread.sleep(200); でのみ機能するものは何もありません。send と receive の間で (1) を見ると、listen() が早すぎて一部しかダウンロードされていないようです...
手伝って頂けますか?
main.cs
public partial class MainWindow : Window
{
public MainWindow()
{
InitializeComponent();
}
private void connectionButton_Click(object sender, RoutedEventArgs e)
{
var url = "209.9.238.6:6042";
var sockHelp = new SocketHelper(url);
sockHelp.onConnect += sockHelp_onConnect;
sockHelp.connect();
}
void testDebug(string str) {
Action action = () => debugTxt.Text = str;
Dispatcher.BeginInvoke(action);
}
void sockHelp_onConnect(object sender, SocketHelperEventArgs e)
{
var sockHelp = sender as SocketHelper;
testDebug("Connected");
var header = "";
header+="GET / HTTP/1.0\r\n";
header+="Accept: */*\r\n";
header+="Host: 209.9.238.6\r\n";
header+="Connection: close\r\n\r\n";
sockHelp.onSend += sockHelp_onSend;
sockHelp.sendAsync(Encoding.UTF8.GetBytes(header));
}
private void sockHelp_onSend(object sender, SocketAsyncEventArgs e)
{
var sockHelp = sender as SocketHelper;
sockHelp.onReceive+=sockHelp_onReceive;
//Thread.Sleep(200); (1) uncomment this line... to make works
sockHelp.listen();
}
void sockHelp_onReceive(object sender, SocketAsyncEventArgs arg_)
{
testDebug("Receiving");
var t = Encoding.UTF8.GetString(arg_.Buffer);
var idx = IndexOf(arg_.Buffer, new byte[] { 0x0d, 0x0a, 0x0d, 0x0a });
if (idx < 0)
{
testDebug(Encoding.UTF8.GetString(arg_.Buffer));
return ;
}
byte[] binBuff = new byte[idx + 1];
System.Buffer.BlockCopy(arg_.Buffer, 0, binBuff, 0, idx + 1);
testDebug(Encoding.UTF8.GetString(binBuff));
}
private int IndexOf(byte[] searchIn, byte[] searchFor)
{
if ((searchIn != null) && (searchIn != null))
{
if (searchFor.Length > searchIn.Length) return 0;
for (int i = 0; i < searchIn.Length; i++)
{
int startIndex = i;
bool match = true;
for (int j = 0; j < searchFor.Length; j++)
{
if (searchIn[startIndex] != searchFor[j])
{
match = false;
break;
}
else if (startIndex < searchIn.Length)
{
startIndex++;
}
}
if (match)
return startIndex - searchFor.Length;
}
}
return -1;
}
}
}
helper.cs
namespace TestSocket
{
/// <summary>
/// </summary>
public class SocketHelperEventArgs : EventArgs
{
public SocketHelperEventArgs(SocketError se)
{
socketError = se;
}
public SocketHelperEventArgs() { }
SocketError socketError;
SocketAsyncEventArgs args;
}
public class SocketHelper
{
byte[] _buffer = new byte[1024*2];
SocketAsyncEventArgs _args = new SocketAsyncEventArgs();
readonly Socket _socket;
public event EventHandler<SocketHelperEventArgs> onError;
public event EventHandler<SocketHelperEventArgs> onConnect;
public event EventHandler<SocketAsyncEventArgs> onReceive;
public event EventHandler<SocketAsyncEventArgs> onSend;
public SocketHelper(string url)
{
int port=0;
string[] addressVector = url.Split(':');
if (addressVector.Length == 1)
port = 80;
else
port = int.Parse(addressVector[1]);
_args.RemoteEndPoint = new DnsEndPoint(addressVector[0], port); ;
_args.Completed += SocketAsyncEventArgs_Completed;
_socket = new Socket(AddressFamily.InterNetwork, SocketType.Stream, ProtocolType.Tcp);
}
public void listen()
{
_args.SetBuffer(_buffer, 0, _buffer.Length);
_socket.ReceiveAsync(_args);
}
public void connect()
{
bool completesAsynchronously = _socket.ConnectAsync(_args);
if (!completesAsynchronously)
{
SocketAsyncEventArgs_Completed(_args.ConnectSocket, _args);
}
}
public void sendAsync(byte[] data) {
_args.SetBuffer(data, 0, data.Length);
_socket.SendAsync(_args);
}
private void SocketAsyncEventArgs_Completed(object sender, SocketAsyncEventArgs e)
{
// check for errors
if (e.SocketError != SocketError.Success)
{
if (onError != null) onError(this, new SocketHelperEventArgs(e.SocketError));
CleanUp(e);
return;
}
switch (e.LastOperation)
{
case SocketAsyncOperation.Connect:
if (onConnect != null) onConnect(this, EventArgs.Empty as SocketHelperEventArgs);
break;
case SocketAsyncOperation.Send:
if (onSend!= null) onSend(this, e);
break;
case SocketAsyncOperation.Receive:
if (onReceive != null) onReceive(this,e);
break;
}
}
private void CleanUp(SocketAsyncEventArgs e)
{
if (e.ConnectSocket != null)
{
e.ConnectSocket.Shutdown(SocketShutdown.Both);
e.ConnectSocket.Close();
}
}
}
}