Справочник функций

Ваш аккаунт

Войти через: 
Забыли пароль?
Регистрация
Информацию о новых материалах можно получать и без регистрации:

Почтовая рассылка

Подписчиков: -1
Последний выпуск: 19.06.2015

Работа с SOCKET.

15K
02 июня 2007 года
kant
64 / / 02.06.2007
Всем привет !

Я мясец назад перешел на C, за это время научился немношка работать на нем.
Только немогу никак написат программу типа klient-server , вот на некорых сайтах нашел какие-то статьи по сетевым работам на C .Как только я напишу что-нибудь такое у себя в компиляторе она выдает ошибку ....
Есть 3 компилятора LCC-WIN32,DEV-C++,Microsoft C++ только ни в одном с них работает те примеры что показаны в стаьтях ....
Вот шас хотел кого нибудь попросить чтоб объяснил по точнее как работать с SOCKET в этих компиляторах ...
Спасибо !
16K
02 июня 2007 года
right_systems
29 / / 08.11.2006
Ты бы показал что ты такое написал, может и ответить проще было бы. Кроме того не плохо было бы посмотреть какие именно ошибки компилятор выводит.
Пока в голову приходят 2 вопроса:
1. Есть ли в твоем .h строка #include <winsock.h>?
2. Есть ли в твоем .cpp строка #include "stdafx.h"?
245
03 июня 2007 года
~ArchimeD~
1.4K / / 24.07.2006
Самое главное - напиши, какую ошибку выдает. Но исходники тоже покажи. Мир не ограничивается LCC-WIN32, DEV-C++, Microsoft C++, есть и другие компиляторы и другие платформы, и понять, че там у тя не работает, погадав на картах, нельзя.
15K
03 июня 2007 года
kant
64 / / 02.06.2007
Цитата: ~ArchimeD~
Самое главное - напиши, какую ошибку выдает. Но исходники тоже покажи. Мир не ограничивается LCC-WIN32, DEV-C++, Microsoft C++, есть и другие компиляторы и другие платформы, и понять, че там у тя не работает, погадав на картах, нельзя.



Да я знаю что есть и другие компиляторы...
Вот исходники :

Код:
#include <winsock2.h>
#include <stdio.h>
#include <windows.h>

int main(void)
{
   WSADATA wsadata;
   WSAStartup(MAKEWORD(2,0),&wsadata);
         SOCKET soc=socket(AF_INET,SOCK_STREAM,IPPROTO_TCP);
   struct sockaddr_in adrs;
   adrs.sin_family=AF_INET;
   adrs.sin_port=htons(4488);
   adrs.sin_addr.s_addr=htonl(INADDR_ANY);

bind(soc,(SOCKADDR*)&adrs),sizeof(adrs);
listen(soc,3);
}


А здесь и ошибкa :Insufficient number of arguments to 'bind'.
вот и все...
15K
03 июня 2007 года
kant
64 / / 02.06.2007
Цитата: right_systems
Ты бы показал что ты такое написал, может и ответить проще было бы. Кроме того не плохо было бы посмотреть какие именно ошибки компилятор выводит.
Пока в голову приходят 2 вопроса:
1. Есть ли в твоем .h строка #include <winsock.h>?
2. Есть ли в твоем .cpp строка #include "stdafx.h"?




А я думал что шас уже работают с <winsock2.h> :)

15K
03 июня 2007 года
kant
64 / / 02.06.2007
Уже понял где была ошибка .
Вот bind(soc,(SOCKADDR*)&adrs),sizeof(adrs); это должно была быт
так:bind(soc,(SOCKADDR*)&adrs,sizeof(adrs));
Надеюсь видите разницу ...
Только шас у меня опять проблема незнаю как правильно написать функцию 'accept()'
29K
05 июня 2007 года
ShigZhip
6 / / 05.06.2007
Цитата: kant
...
Только шас у меня опять проблема незнаю как правильно написать функцию 'accept()'


Можно, например, создать отдельный поток и уже в нем вызывать accept() бесконечно.......
Или же можно использовать WSAAsyncSelect.

15K
05 июня 2007 года
kant
64 / / 02.06.2007
Цитата: ShigZhip
Можно, например, создать отдельный поток и уже в нем вызывать accept() бесконечно.......
Или же можно использовать WSAAsyncSelect.



С этим accept() можешь показат, как создат новый поток ? :)))

29K
05 июня 2007 года
ShigZhip
6 / / 05.06.2007
Цитата: kant
С этим accept() можешь показат, как создат новый поток ? :)))


легко

Код:
DWORD WINAPI acceptFunc(LPVOID){
  SOCKET s2;
  int size=sizeof(sockaddr_in);
  HANDLE hClientThread;
  while(1){
    s2=accept(Form1->getSocket(),(sockaddr*)&Form1->getAddr_in(),&size);
    if(INVALID_SOCKET==s2){
      ...
}
        hClientThread=CreateThread(NULL,0,clientFunc,&s2,0,NULL);
        Form1->inc();
        Form1->servLog->Lines->Add("Client connected to "+IntToStr(s2)+" socket.");
        Form1->bar->Panels[0].operator[](3)->Text="Total users count:"+IntToStr(Form1->getUsers());
    }
//  return 0;
}
29K
05 июня 2007 года
ShigZhip
6 / / 05.06.2007
Цитата: kant
С этим accept() можешь показат, как создат новый поток ? :)))


легко

Код:
DWORD WINAPI acceptFunc(LPVOID){
  SOCKET s2;
  HANDLE hClientThread;
  while(1){
    s2=accept(/*твой сокет*/,/*твоя структурка*,...);
    if(INVALID_SOCKET==s2){
      ...
    }
    hClientThread=CreateThread(NULL,0,clientFunc,&s2,0,NULL);
    return 0;
}
DWORD WINAPI clientFunc(LPVOID s){
  SOCKET s2=*(SOCKET*)s;
  char mess[256];
  int rez;
  while(1){
    rez=recv(s2,mess,255,0);
    if(SOCKET_ERROR==rez){
     ...
    }
  }
  return 0;
}

а после своего listen() вставляешь типа:
 
Код:
HANDLE hThread;
hThread=CreateThread(NULL,0,acceptFunc,NULL,0,NULL);

я своя первую лбораторную по сетям так сдавал.
Но через WSAAsyncSelect, IMHO, легче работать.
15K
05 июня 2007 года
kant
64 / / 02.06.2007
Цитата: ShigZhip
легко
Код:
DWORD WINAPI acceptFunc(LPVOID){
  SOCKET s2;
  HANDLE hClientThread;
  while(1){
    s2=accept(/*твой сокет*/,/*твоя структурка*,...);
    if(INVALID_SOCKET==s2){
      ...
    }
    hClientThread=CreateThread(NULL,0,clientFunc,&s2,0,NULL);
    return 0;
}
DWORD WINAPI clientFunc(LPVOID s){
  SOCKET s2=*(SOCKET*)s;
  char mess[256];
  int rez;
  while(1){
    rez=recv(s2,mess,255,0);
    if(SOCKET_ERROR==rez){
     ...
    }
  }
  return 0;
}

а после своего listen() вставляешь типа:
 
Код:
HANDLE hThread;
hThread=CreateThread(NULL,0,acceptFunc,NULL,0,NULL);

я своя первую лбораторную по сетям так сдавал.
Но через WSAAsyncSelect, IMHO, легче работать.





Спасибо !

15K
06 июня 2007 года
kant
64 / / 02.06.2007
Вот клиент-сервер , помойму нормально соединяються только клиент не хочет послат сообщени серверу или сервер не хочет принимать , скажите пожалуйста где я зделал ошибку

Клиент :
Код:
#include <winsock2.h>
#include <stdio.h>



int main(void)
{
        printf("#### KLIENT ####\n\n\n");
    WSADATA wsd;
    struct hostent *hst;
    SOCKET s;
    char buf[1024],HOST_NAME[1024];
    strcpy(HOST_NAME,"127.0.0.1");


int er=WSAStartup(MAKEWORD(2,0),&wsd);
    if(er!=0){
        printf("Error:WSAStartup.\n\a");
    }
    else{
    printf("WSAStartup... ok\n");
        }

int err=(s=socket(AF_INET,SOCK_STREAM,IPPROTO_TCP));
    if(err==SOCKET_ERROR){
        printf("Error:SOCKET ERROR\n\a");
        }
    else{
        printf("SOCKET... ok\n");
        }
struct sockaddr_in adr;
adr.sin_family=AF_INET;
adr.sin_addr.s_addr=inet_addr(HOST_NAME);
adr.sin_port=htons(5050);

if(adr.sin_addr.s_addr==INADDR_NONE)
    {
         hst=gethostbyname(HOST_NAME);
    }


if((connect(s,(SOCKADDR*)&adr,sizeof(adr)))==SOCKET_ERROR){
        printf("Error:Connect failed!\n\a");
      }
        scanf("%s",&buf);
        send(s,buf,strlen(buf),0);

}


Вот и сервер:
Код:
#include <winsock2.h>
#include <windows.h>
#include <stdio.h>

int main(void)
{
int iSize,s2;
char buf[256];
SOCKET s;
WSADATA wsd;
                printf("#### SERVER ####\n\n");
    int er=WSAStartup(MAKEWORD(2,2),&wsd);

if(er!=0){
            printf("Error WSAStartup\n\a");
          }
else{
            printf("WSAStartup... ok\n");
     }

if((er=(s=socket(AF_INET,SOCK_STREAM,IPPROTO_TCP)))==SOCKET_ERROR){
            printf("Socket error!\n\a");
    }
else{
            printf("SOCKET... ok\n");
    }
 struct sockaddr_in adr;
 adr.sin_family=AF_INET;
 adr.sin_addr.s_addr=htonl(INADDR_ANY);
adr.sin_port=htons(5050);

if((bind(s,(SOCKADDR*)&adr,sizeof(adr)))==SOCKET_ERROR)
    {
        printf("Error bind!\n\a");
    }
else
    {
        printf("bind... ok\n");
        listen(s,3);
        printf("listen... ok\n");
    }
iSize=sizeof(adr);

     while(1){
            accept(s,(SOCKADDR*)&adr,&iSize);
         }
     while(1){
            recv(s,buf,strlen(buf),0);
            printf("%s",buf);
         }

}
29K
07 июня 2007 года
ShigZhip
6 / / 05.06.2007
у тебя первый цикл while на сервере работает постоянно.
я ж писал, надо либо поток создавать либо через WSAAsyncSelect работать. Хотя я не знаю как консольное приложение будет WSAAsyncSelect использовать, там же ей надо HANDLE приложения скармливать......
6.4K
07 июня 2007 года
Host
122 / / 22.09.2005
Цитата: kant

while(1){
accept(s,(SOCKADDR*)&adr,&iSize);
}



Функция accept() возвращает "дочерний" сокет, который и будет общаться с клиентом.

Примерно так:

Код:
[SIZE=2]SOCKET sChild;[/SIZE]
 
[SIZE=2][COLOR=#0000ff]while[/COLOR][/SIZE][SIZE=2](1)[/SIZE]
[SIZE=2]{[/SIZE]
[SIZE=2]  sChild = accept(s,(SOCKADDR*)&adr,&iSize);[/SIZE]
[SIZE=2][COLOR=#0000ff]  if[/COLOR][/SIZE][SIZE=2](sChild != INVALID_SOCKET ) [/SIZE][SIZE=2][COLOR=#0000ff]break[/COLOR][/SIZE][SIZE=2];[/SIZE]
[SIZE=2]}[/SIZE]
[SIZE=2][COLOR=#0000ff]while[/COLOR][/SIZE][SIZE=2](1)[/SIZE]
[SIZE=2]{[/SIZE]
[SIZE=2]  recv(sChild,buf,strlen(buf),0);[/SIZE]
[SIZE=2]  printf([/SIZE][SIZE=2][COLOR=#800000]"%s"[/COLOR][/SIZE][SIZE=2],buf);[/SIZE]
[SIZE=2]}[/SIZE]
15K
07 июня 2007 года
kant
64 / / 02.06.2007
Цитата: Host
Функция accept() возвращает "дочерний" сокет, который и будет общаться с клиентом.

Примерно так:
Код:
[SIZE=2]SOCKET sChild;[/SIZE]
 
[SIZE=2][COLOR=#0000ff]while[/COLOR][/SIZE][SIZE=2](1)[/SIZE]
[SIZE=2]{[/SIZE]
[SIZE=2]  sChild = accept(s,(SOCKADDR*)&adr,&iSize);[/SIZE]
[SIZE=2][COLOR=#0000ff]  if[/COLOR][/SIZE][SIZE=2](sChild != INVALID_SOCKET ) [/SIZE][SIZE=2][COLOR=#0000ff]break[/COLOR][/SIZE][SIZE=2];[/SIZE]
[SIZE=2]}[/SIZE]
[SIZE=2][COLOR=#0000ff]while[/COLOR][/SIZE][SIZE=2](1)[/SIZE]
[SIZE=2]{[/SIZE]
[SIZE=2]  recv(sChild,buf,strlen(buf),0);[/SIZE]
[SIZE=2]  printf([/SIZE][SIZE=2][COLOR=#800000]"%s"[/COLOR][/SIZE][SIZE=2],buf);[/SIZE]
[SIZE=2]}[/SIZE]




ya shas tak i delayu tolko, etot socket oshibku vidaet ....

6.4K
08 июня 2007 года
Host
122 / / 22.09.2005
Цитата: kant
ya shas tak i delayu tolko, etot socket oshibku vidaet ....



Нет никаких ошибок, просто буфер для приема у тебя равен нулю

Цитата:
while(1){
recv(s,buf,strlen(buf),0);
printf("%s",buf);
}



измени второй цикл, и не забывай о окончании строки:

 
Код:
[SIZE=2][COLOR=#0000ff]while[/COLOR][/SIZE][SIZE=2](1)[/SIZE]
[SIZE=2]{[/SIZE]
[SIZE=2]strcpy(buf, [/SIZE][SIZE=2][COLOR=#800000]""[/COLOR][/SIZE][SIZE=2]);[/SIZE]
[SIZE=2][COLOR=#0000ff]int[/COLOR][/SIZE][SIZE=2] ret = recv(sChild ,buf , 256, 0);[/SIZE]
[SIZE=2]buf[ret] = [/SIZE][SIZE=2][COLOR=#800000]'\0'[/COLOR][/SIZE][SIZE=2];[/SIZE]
[SIZE=2]printf([/SIZE][SIZE=2][COLOR=#800000]"%s"[/COLOR][/SIZE][SIZE=2],buf);[/SIZE]
[SIZE=2]}[/SIZE]


Да, на клиенте send() можеш в цикл загнать, а то больше одного сообщения не передаш. и вот это, по-моему у тебя лишнее:
Цитата:
if(adr.sin_addr.s_addr==INADDR_NONE)
{
hst=gethostbyname(HOST_NAME);
}

15K
08 июня 2007 года
kant
64 / / 02.06.2007
Da ti prav eto u menya lishnee , tak kak ya nachinayushiy na C ya probuyu vse chto ya umeyu na nem delat :) chtob potom ne imel s etim problemi ....
A tak, spasibo tebe bolshoe !
Реклама на сайте | Обмен ссылками | Ссылки | Экспорт (RSS) | Контакты
Добавить статью | Добавить исходник | Добавить хостинг-провайдера | Добавить сайт в каталог