PDA

Просмотр полной версии : С# и сокеты


[NiGHT]DarkAngel
08.05.2009, 10:00
Пишу программку,ее основой является мини подобие http сервера,проблема заключается в следующем,когда из студии я компилирую проект,запускает сервер и я могу обратиться к нему браузером и сервер вернет браузере ответ,который соответственно я увижу в окне браузера... но если я не перезапуская свой сервер попрошу отдать в браузер другую страничку,то браузер пишет,что не может соединиться с сервером :( ... помогите пожалуйста решить проблему,заранее очень сильно благодарен.

ЗЫ Сильно ногами за код не пинать,только учусь :rolleyes:


using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
using System.Net;
using System.Net.Sockets;

namespace http_agent
{

class http_serv
{
private const int MAX_BUFFER = 4096;
private const string notfound = "HTTP/1.1 404 File not found\n\n";
private const string header_send = "HTTP/1.1 200 OK\nServer: tinyHttp\nConnection: close\nContent-Type: text/html\n\n";
Socket listenfd = null;
IPEndPoint pe = null;

public int initHTTPServ()
{

//if(listenfd.) listenfd.Close(); -- проверить существует ли сокет,если да то закрыть его...
listenfd = new Socket(AddressFamily.InterNetwork,SocketType.Strea m,ProtocolType.Tcp);
pe = new IPEndPoint(IPAddress.Any, 8080);

listenfd.SetSocketOption(SocketOptionLevel.Socket, SocketOptionName.ReuseAddress,false);

listenfd.Bind(pe);

listenfd.Listen(1);

System.Console.WriteLine("HTTP Server start ...");
return 0;
}

public void checkHttpServer()
{
//Подключаемся к сокету и вызываем функцию обслуживания запроса
handleConnection(listenfd.Accept());
}


public string getFileName(string inbuf, int start)
{
int i = start, j = 0;
string ret = "";
char[] outs = new char[80 + 1];

while (inbuf[i] == ' ') i++;

for (; i < inbuf.Length; i++)
{
if (inbuf[i] == ' ')
{
break;
}
outs[j++] = inbuf[i];
}

ret = new string(outs,0,j);

if (ret == "/")
{
ret = "/index.html";
}

return ret;
}

public void emitHTTPResponseHeader(Socket connfd)
{
connfd.Send(Encoding.ASCII.GetBytes(header_send));
}

public void handleConnection(Socket connfd)
{
Console.WriteLine("Handle Connections...");
int len, max, loop;
byte[] buffer = new byte[http_serv.MAX_BUFFER+1];
string filename = "";
string str_in_sock = "";

max = 0; loop = 1;
while (loop == 1)
{
len = connfd.Receive(buffer);
buffer[max+len] = 0;
if (len <= 0) return;
max += len;
if ((buffer[max-4] == 0x0d) && (buffer[max-3] == 0x0a) && (buffer[max-2] == 0x0d) && (buffer[max-1] == 0x0a)) loop = 0;
}

str_in_sock = Encoding.ASCII.GetString(buffer, 0, max);

if (str_in_sock.Substring(0, 3) == "GET") //если метод GET
{

filename = getFileName(str_in_sock, 4); //получаем имя запрашиваемого файла файла


if (filename == "/index.html") { Console.WriteLine("GET /index.html");}//emitNews( connfd );
else if (filename == "/config.html") { Console.WriteLine("GET /config.html");} //emitConfig( connfd );
else if (filename == "/art") { Console.WriteLine("GET /art"); } //emitArticle( connfd, filename );
else
{
connfd.Send(Encoding.ASCII.GetBytes(notfound));
connfd.Close();
Console.WriteLine("GET Not Found");
}

}else if (str_in_sock.Substring(0, 4) == "POST") //Если метод POST
{

filename = getFileName(str_in_sock, 4);

if (filename == "/clear")
{
//clearEntries();
emitHTTPResponseHeader(connfd);
buffer = Encoding.ASCII.GetBytes("<P><H1>Нажмите назад и перезагрузите страницу</H1><P>\n\n");
connfd.Send(buffer);
} else
{
connfd.Send(Encoding.ASCII.GetBytes(notfound));
connfd.Close();
}
}
else
{
connfd.Send(Encoding.ASCII.GetBytes("HTTP/1.1 501 Not Implemented\n\n"));

}
}
}


class Program
{
static void Main(string[] args)
{
http_serv serv = new http_serv();
serv.initHTTPServ();
serv.checkHttpServer();
System.Console.ReadLine();
}
}
}

Algol
08.05.2009, 10:36
Не удивительно, ведь ты же обрабатываешь только один запрос пользователя, после чего программа просто заканчивает выполнение...

Нужно handleConnection(listenfd.Accept()); хотя бы в цикле выполнять. А лучше асинхронно или с потоками...

[NiGHT]DarkAngel
08.05.2009, 14:55
Спасибо огромное,во я дурак то :)

[NiGHT]DarkAngel
24.05.2009, 23:00
Подниму небольшой вопросик про сокеты опять :) ... Можно пинать меня сильно , но главное что бы было за что :-D... есть вот такой код


nntp_he = Dns.GetHostEntry(nntpServer);

foreach(IPAddress tmp_ip_serv in nntp_he.AddressList)
{
ip_nntp_serv = tmp_ip_serv;
}

nntp_conn = new Socket(AddressFamily.InterNetwork, SocketType.Stream, ProtocolType.Tcp);
nntp_ep = new IPEndPoint(ip_nntp_serv, 119);

Console.WriteLine("Соединяемся с " + nntpServer);

nntp_conn.Connect(nntp_ep);

buffer = new byte[gVarible.MAX_LINE + 1];
nntp_conn.Receive(buffer);
Console.WriteLine(Encoding.ASCII.GetString(buffer) );


buffer = null;

nntp_conn.Send(Encoding.ASCII.GetBytes("c"));

Console.WriteLine("q");

byte[] buffer2 = new byte[1024];

Console.WriteLine("q2");

nntp_conn.Receive(buffer2);

Console.WriteLine("q3");

Console.WriteLine(Encoding.ASCII.GetString(buffer2 ));



Проблема в том что он всего лишь один раз принимает данные из сокета ,после соединения,а когда я отправляю серверу через открытый с ним сокет данные ,а затем пытаюсь прочитать....

nntp_conn.Receive(buffer2);
Console.WriteLine("q3");
Console.WriteLine(Encoding.ASCII.GetString(buffer2 ));

Вот эта часть кода вообще не выполняется,доходит только до Console.WriteLine("q2"); и все,буду безумно благодарен и поставлю плюсики от всей души,если поможите разобраться с этой проблемкой.Заранее спасибо!

Juda
24.05.2009, 23:31
Может полный исходник кинь. Чтоб и сервер и клиент было видно.

Juda
24.05.2009, 23:43
вот исходник чата на C#. Посмотри че да как. http://sourceforge.net/project/downloading.php?group_id=71539&filename=SharpChat-1.1.1.zip&a=95975655

[NiGHT]DarkAngel
25.05.2009, 07:17
Это и был клиент,а в роли сервера выступает сервер nntp новостей,к которому я тут соответственно и подключаюсь

Juda
25.05.2009, 17:15
Чувак, у тебя есть исходник, комп, мозг, дебагер и еще есть MSDN, в котором куча примеров по сокетам. Пройдись дебагером по коду (не по мозгам ;) ), посмотри че не работает. Смысл два дня ждать ответа на форуме, если самому можно за часик все склепать. :)

Algol
25.05.2009, 19:01
DarkAngel']Вот эта часть кода вообще не выполняется,доходит только до Console.WriteLine("q2"); и все

Что "и все"? Выпадает ошибка? Какая?
Поставь try, отлови ошибку.

[NiGHT]DarkAngel
25.05.2009, 21:38
Вот именно что ошибки никакой нет :( ,просто не выполняется дальше код ... не один из трех исключения для сокета через catch не выпадает ... возьму совет Juda пойду дебаггером и снифером :)

[NiGHT]DarkAngel
26.05.2009, 07:11
Все тема клоусед,разобрался косяк был мой в 2 символах , когда я посылал серверу через сенд в конце не писал \r\n и поэтому сервак думал что я еще не закончил отправлять данные ему и принимать соответственно от сервера нечего было :(