Panel użytkownika
Nazwa użytkownika:
Hasło:
Nie masz jeszcze konta?

[WinSock] zwalnianie portu

Ostatnio zmodyfikowano 2010-06-10 00:00
Autor Wiadomość
ison
Temat założony przez niniejszego użytkownika
» 2010-06-07 20:46:38
kod jest niezmiernie długi, piszę komunikator z opcją multi-clienta i hosta w konsoli. Komunikator do rozmawiania 1 osoby z jedną inną mam już napisany i mogę tu kiedyś udostępnić. Postanowiłem go polepszyć żeby można było rozmawiać w gronie osób ;)
błąd dotyczy tej linijki:
C/C++
DisconnectEx( sck[ clients_quantify - 1 ], 0, 0, 0 );

sck to tablica SOCKET.
wiem że argumenty są złe gdyż ich jeszcze nie uzupełniałem, fakt faktem że błąd nie tyczy się argumentów tylko undefined reference
P-17768
michalp
» 2010-06-07 20:47:22
@malan: po co skoro to problem linkera nie kompilatora. Czyli nagłówek funkcji jest definicji tylko brak. Idąc dalej pewnie zalinkował nie to co trzeba (albo nie ma tej funkcji w bibliotece).
P-17769
malan
» 2010-06-07 22:57:43
@michalp: No faktycznie ;p.
@ison: Olej tą funkcję :). Prawdopodobnie, aby jej użyć wystarczą 3 kliknięcie, ale nie mam nerwów dziś na taką zabawę ;p. Sory, za kłopot ;p.
Poszukaj tutaj :).
P-17770
ison
Temat założony przez niniejszego użytkownika
» 2010-06-07 23:05:57
ehhh.. dzieki, przejrzałem i nic nie znalazłem. W google jak szukałem to też nie znalazłem odpowiedzi. Chcę tylko usunąć socketa tak żeby mi nie blokował portu... przecież możliwe to to być musi
P-17771
DejaVu
» 2010-06-07 23:32:30
Wklej więc krótki program, który pokazuje nam ten błąd :) Jestem przekonany, że coś zwaliłeś :)
P-17772
ison
Temat założony przez niniejszego użytkownika
» 2010-06-07 23:46:59
ehh, to jest najkrótszy program jaki udało mi się napisać obrazujący mój problem. Ale i tak wg mnie tu nie chodzi o błąd w kodzie tylko zwyczajnie o funkcję usuwającą socketa i zwalniającą port.
C/C++
#include <iostream.h>
#include <windows.h>
#include <winsock.h>
#include <conio.h>

using namespace std;

void Close()
{
    exit( 0 );
}

int main()
{
    WSADATA WsaDat;
    if( WSAStartup( MAKEWORD( 1, 1 ), & WsaDat ) != 0 )
    {
        printf( "blad\n" );
        system( "pause" );
        Close();
    }
    SOCKET mysocket;
    mysocket = socket( AF_INET, SOCK_STREAM, 0 );
   
    int ip1 = 127, ip2 = 0, ip3 = 0, ip4 = 1;
   
    SOCKADDR_IN SockAddr;
    SockAddr.sin_port = htons( 50 );
    SockAddr.sin_family = AF_INET;
    SockAddr.sin_addr.S_un.S_un_b.s_b1 = ip1;
    SockAddr.sin_addr.S_un.S_un_b.s_b2 = ip2;
    SockAddr.sin_addr.S_un.S_un_b.s_b3 = ip3;
    SockAddr.sin_addr.S_un.S_un_b.s_b4 = ip4;
   
    printf( "1: server   2: klient\n" );
    int wyb;
    scanf( "%d", & wyb );
    if( wyb == 1 )
    while( 1 )
    {
        if( bind( mysocket,( SOCKADDR * )( & SockAddr ), sizeof( SockAddr ) ) == SOCKET_ERROR )
        {
            printf( "Port jest aktualnie uzywany...\n" );
            system( "pause" );
            Close();
        }
       
        listen( mysocket, 1 );
        SOCKET TempSock = SOCKET_ERROR;
        while( TempSock == SOCKET_ERROR )
        {
            TempSock = accept( mysocket, NULL, NULL );
        }
        mysocket = TempSock;
       
        char test[ 100 ];
        recv( mysocket, test, 100, 0 );
        printf( "%s\n", test );
    }
    if( wyb == 2 )
    while( 1 )
    {
        if( connect( mysocket,( SOCKADDR * )( & SockAddr ), sizeof( SockAddr ) ) == SOCKET_ERROR )
        {
            printf( "Brak polaczenia\n" );
            system( "pause" );
            Close();
        }
        char test[ 100 ];
        test[ 0 ] = 'a';
        test[ 1 ] = 0;
        send( mysocket, test, 100, 0 );
    }
    Close();
}

za pierwszym razem ciąg znaków 'test' jest przesyłany dobrze, jeśli chcę np. z innego komputera wysłać nie zamykając servera to nie może zbindować gdyż port jest już aktualnie używany
P-17773
DejaVu
» 2010-06-08 02:25:28
Skoro nie wywołujesz closesocket to jak ma to zadziałać?

Na MSDN'ie masz przykład użycia bind'a (i nie tylko): http://msdn.microsoft.com/en-us/library/ms737550(VS.85).aspx

/edit:
Mhm... połączenie konfiguruje się raz na serwerze, a później je się używa do oporu, tj. dopóki nie zostanie zerwane lub zakończone.

/edit2:
Poza tym bind'a używa się tylko na serwerze.

/edit3:
Małe fragmenty mojego serwera:
C/C++
void CSocket::stop()
{
    if( m_socket == INVALID_SOCKET )
         return;
   
    ::closesocket( m_socket );
    m_socket = INVALID_SOCKET;
}

bool CSocket::bind( SockAddrT & sockAddr ) const
{
    return::bind( m_socket, reinterpret_cast < sockaddr *>( & sockAddr ), sizeof( sockAddr ) ) != SOCKET_ERROR;
}

void TServerTCP::stop()
{
    m_socket.stop();
    {
        boost::mutex::scoped_lock lock( m_csClient );
        for( SocketsT::iterator i = m_sockets.begin(); i != m_sockets.end(); i++ )
             i->stop();
       
        m_sockets.clear();
    }
    m_threads.join_all();
}
Myślę, że wystarczająco dużo napisałem.
P-17775
ison
Temat założony przez niniejszego użytkownika
» 2010-06-08 06:40:55
Może rzeczywiście źle przedstawiłem problem. Nie wywołuję w tym programie closesocket ponieważ nic nie daje. Jeśli go wywoluje to nadal port jest zajęty. Wiem że socketa nie musze kilka razy bindować żeby mieć połączenie z innym komputerem tylko ja chce zrobić tak że nie wiem z ilu komputerów będzie dochodziło to połączenie. Jeśli ktoś już z innego komputera będzie się chciał podłączyć pod ten sam port i wysłać mi ciąg znaków to już się nie będzie dało zbindować nowego połączenia z nim.
Jeśli by pan mógl to proszę o przykład bez zamykania programu o połączenie z kilkoma komputerami (nie koniecznie w tym samym momencie ale przez ten sam port, gdyż trochę uciążliwe to by musiało być że przy połączeniu do czata musiałby ktoś wpisywać kolejny port).
Zwyczajnie chcę zrobić tak że program czeka na dowolny sygnał, jak go dostanie to wypisuje ciąg znaków i o nim kompletnie zapomina, powtarza czynność na tym samym porcie i czeka na sygnał od możliwe że innego komputera.
P-17776
1 2 « 3 » 4 5 6
Poprzednia strona Strona 3 z 6 Następna strona