#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);
}
Работа с SOCKET.
Я мясец назад перешел на C, за это время научился немношка работать на нем.
Только немогу никак написат программу типа klient-server , вот на некорых сайтах нашел какие-то статьи по сетевым работам на C .Как только я напишу что-нибудь такое у себя в компиляторе она выдает ошибку ....
Есть 3 компилятора LCC-WIN32,DEV-C++,Microsoft C++ только ни в одном с них работает те примеры что показаны в стаьтях ....
Вот шас хотел кого нибудь попросить чтоб объяснил по точнее как работать с SOCKET в этих компиляторах ...
Спасибо !
Пока в голову приходят 2 вопроса:
1. Есть ли в твоем .h строка #include <winsock.h>?
2. Есть ли в твоем .cpp строка #include "stdafx.h"?
Самое главное - напиши, какую ошибку выдает. Но исходники тоже покажи. Мир не ограничивается LCC-WIN32, DEV-C++, Microsoft C++, есть и другие компиляторы и другие платформы, и понять, че там у тя не работает, погадав на картах, нельзя.
Цитата: ~ArchimeD~
Самое главное - напиши, какую ошибку выдает. Но исходники тоже покажи. Мир не ограничивается LCC-WIN32, DEV-C++, Microsoft C++, есть и другие компиляторы и другие платформы, и понять, че там у тя не работает, погадав на картах, нельзя.
Да я знаю что есть и другие компиляторы...
Вот исходники :
Код:
А здесь и ошибкa :Insufficient number of arguments to 'bind'.
вот и все...
Цитата: right_systems
Ты бы показал что ты такое написал, может и ответить проще было бы. Кроме того не плохо было бы посмотреть какие именно ошибки компилятор выводит.
Пока в голову приходят 2 вопроса:
1. Есть ли в твоем .h строка #include <winsock.h>?
2. Есть ли в твоем .cpp строка #include "stdafx.h"?
Пока в голову приходят 2 вопроса:
1. Есть ли в твоем .h строка #include <winsock.h>?
2. Есть ли в твоем .cpp строка #include "stdafx.h"?
А я думал что шас уже работают с <winsock2.h> :)
Вот bind(soc,(SOCKADDR*)&adrs),sizeof(adrs); это должно была быт
так:bind(soc,(SOCKADDR*)&adrs,sizeof(adrs));
Надеюсь видите разницу ...
Только шас у меня опять проблема незнаю как правильно написать функцию 'accept()'
Цитата: kant
...
Только шас у меня опять проблема незнаю как правильно написать функцию 'accept()'
Только шас у меня опять проблема незнаю как правильно написать функцию 'accept()'
Можно, например, создать отдельный поток и уже в нем вызывать accept() бесконечно.......
Или же можно использовать WSAAsyncSelect.
Цитата: ShigZhip
Можно, например, создать отдельный поток и уже в нем вызывать accept() бесконечно.......
Или же можно использовать WSAAsyncSelect.
Или же можно использовать WSAAsyncSelect.
С этим accept() можешь показат, как создат новый поток ? :)))
Цитата: 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;
}
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;
}
Цитата: 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;
}
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);
hThread=CreateThread(NULL,0,acceptFunc,NULL,0,NULL);
я своя первую лбораторную по сетям так сдавал.
Но через WSAAsyncSelect, IMHO, легче работать.
Цитата: ShigZhip
легко
а после своего listen() вставляешь типа:
я своя первую лбораторную по сетям так сдавал.
Но через WSAAsyncSelect, IMHO, легче работать.
Код:
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;
}
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);
hThread=CreateThread(NULL,0,acceptFunc,NULL,0,NULL);
я своя первую лбораторную по сетям так сдавал.
Но через WSAAsyncSelect, IMHO, легче работать.
Спасибо !
Клиент :
Код:
#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 <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);
}
}
#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);
}
}
я ж писал, надо либо поток создавать либо через WSAAsyncSelect работать. Хотя я не знаю как консольное приложение будет WSAAsyncSelect использовать, там же ей надо HANDLE приложения скармливать......
Цитата: 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]
[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]
Цитата: 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]
[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 ....
Цитата: kant
ya shas tak i delayu tolko, etot socket oshibku vidaet ....
Нет никаких ошибок, просто буфер для приема у тебя равен нулю
Цитата:
while(1){
recv(s,buf,strlen(buf),0);
printf("%s",buf);
}
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]
[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);
}
{
hst=gethostbyname(HOST_NAME);
}
A tak, spasibo tebe bolshoe !