С Новым годом! Форум программистов, компьютерный форум, киберфорум
C++ Builder
Войти
Регистрация
Восстановить пароль
Блоги Сообщество Поиск Заказать работу  
 
Рейтинг 4.65/46: Рейтинг темы: голосов - 46, средняя оценка - 4.65
 Аватар для lizard
0 / 0 / 0
Регистрация: 20.09.2011
Сообщений: 14

Многопоточный TCP сервер

19.10.2011, 12:43. Показов 9540. Ответов 10
Метки нет (Все метки)

Студворк — интернет-сервис помощи студентам
Привет всем.

У меня есть задача написать клиент-серверное приложение, с определенными условиями.
С сабжем я еще не работал, поэтому для начала хочу запустить простой сервер и подконектиться к нему, обменяться пакетами для теста, потом ковырять дальше. Нашел хороший пример на сайте у майкрософта (http://msdn.microsoft.com/ru-r... S.85).aspx), есть исходники и документация подробная. Сервер скомпилился хорошо. А вот с клиентом проблемы.

Кто подскажет в чем дело?

C++
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
#define WIN32_LEAN_AND_MEAN
 
#include <windows.h>
#include <winsock2.h>
#include <ws2tcpip.h>
#include <stdlib.h>
#include <stdio.h>
 
 
// Need to link with Ws2_32.lib, Mswsock.lib, and Advapi32.lib
#pragma comment (lib, "Ws2_32.lib")
#pragma comment (lib, "Mswsock.lib")
#pragma comment (lib, "AdvApi32.lib")
 
 
#define DEFAULT_BUFLEN 512
#define DEFAULT_PORT "27015"
 
int __cdecl main(int argc, char **argv) 
{
    WSADATA wsaData;
    SOCKET ConnectSocket = INVALID_SOCKET;
    struct addrinfo *result = NULL,
                    *ptr = NULL,
                    hints;
    char *sendbuf = "this is a test";
    char recvbuf[DEFAULT_BUFLEN];
    int iResult;
    int recvbuflen = DEFAULT_BUFLEN;
    
    // Validate the parameters
    if (argc != 2) {
        printf("usage: %s server-name\n", argv[0]);
        return 1;
    }
 
    // Initialize Winsock
    iResult = WSAStartup(MAKEWORD(2,2), &wsaData);
    if (iResult != 0) {
        printf("WSAStartup failed with error: %d\n", iResult);
        return 1;
    }
 
    ZeroMemory( &hints, sizeof(hints) );
    hints.ai_family = AF_UNSPEC;
    hints.ai_socktype = SOCK_STREAM;
    hints.ai_protocol = IPPROTO_TCP;
 
    // Resolve the server address and port
    iResult = getaddrinfo(argv[1], DEFAULT_PORT, &hints, &result);
    if ( iResult != 0 ) {
        printf("getaddrinfo failed with error: %d\n", iResult);
        WSACleanup();
        return 1;
    }
 
    // Attempt to connect to an address until one succeeds
    for(ptr=result; ptr != NULL ;ptr=ptr->ai_next) {
 
        // Create a SOCKET for connecting to server
        ConnectSocket = socket(ptr->ai_family, ptr->ai_socktype, 
            ptr->ai_protocol);
        if (ConnectSocket == INVALID_SOCKET) {
            printf("socket failed with error: %ld\n", WSAGetLastError());
            WSACleanup();
            return 1;
        }
 
        // Connect to server.
        iResult = connect( ConnectSocket, ptr->ai_addr, (int)ptr->ai_addrlen);
        if (iResult == SOCKET_ERROR) {
            closesocket(ConnectSocket);
            ConnectSocket = INVALID_SOCKET;
            continue;
        }
        break;
    }
 
    freeaddrinfo(result);
 
    if (ConnectSocket == INVALID_SOCKET) {
        printf("Unable to connect to server!\n");
        WSACleanup();
        return 1;
    }
 
    // Send an initial buffer
    iResult = send( ConnectSocket, sendbuf, (int)strlen(sendbuf), 0 );
    if (iResult == SOCKET_ERROR) {
        printf("send failed with error: %d\n", WSAGetLastError());
        closesocket(ConnectSocket);
        WSACleanup();
        return 1;
    }
 
    printf("Bytes Sent: %ld\n", iResult);
 
    // shutdown the connection since no more data will be sent
    iResult = shutdown(ConnectSocket, SD_SEND);
    if (iResult == SOCKET_ERROR) {
        printf("shutdown failed with error: %d\n", WSAGetLastError());
        closesocket(ConnectSocket);
        WSACleanup();
        return 1;
    }
 
    // Receive until the peer closes the connection
    do {
 
        iResult = recv(ConnectSocket, recvbuf, recvbuflen, 0);
        if ( iResult > 0 )
            printf("Bytes received: %d\n", iResult);
        else if ( iResult == 0 )
            printf("Connection closed\n");
        else
            printf("recv failed with error: %d\n", WSAGetLastError());
 
    } while( iResult > 0 );
 
    // cleanup
    closesocket(ConnectSocket);
    WSACleanup();
 
    return 0;
}

Ошибка:

Unable to open file ADVAPI32.LIB


Advapi32.dll в system32 лежит. Запускаю в C++Builder6 в Win7.

Буду рад любым советам и разъяснениям.
0
Programming
Эксперт
39485 / 9562 / 3019
Регистрация: 12.04.2006
Сообщений: 41,671
Блог
19.10.2011, 12:43
Ответы с готовыми решениями:

Многопоточный TCP сервер
Доброго времени суток! Я уже долгое время пытаюсь написать сервер, который может принимать много соединений с многими клиентами...

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

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

10
 Аватар для cpp_developer
20124 / 5691 / 417
Регистрация: 09.04.2010
Сообщений: 22,546
Записей в блоге: 1
19.10.2011, 12:50
если ADVAPI32.LIB существует - добавьте ее в проект: Project->Add to Project... и укажите вашу ADVAPI32.LIB
или укажите в настройках проекта - в Library Path , Include Path путь к либе.

если ADVAPI32.LIB не существует - сделайте ее из Advapi32.dll:
implib.exe в каталоге Bin Билдера, строка запуска:
Command-Line Syntax

IMPLIB <options> <LibName>[.lib] [<DefFiles>... | <DLLs>... ]^
[@<ResponseFile> | <sourcename> ] [<sourcename> ...]
IMPLIB.EXE

Проще всего поместить implib.exe и Advapi32.dll в отдельную папку и выполнить:
implib.exe ADVAPI32.LIB Advapi32.dll
, получив, таким разом, нужную ADVAPI32.LIB
1
 Аватар для lizard
0 / 0 / 0
Регистрация: 20.09.2011
Сообщений: 14
19.10.2011, 13:43  [ТС]
Cгенерил *.lib файлы из *.dll виндовсовских. Добавил в проект через Add to project, однако ошибка осталась.

Добавлено через 14 минут
и в сервере таким вот образом добавляется
C++
1
#pragma comment (lib, "Ws2_32.lib")
она работает нормально без дополнительных действий

Добавлено через 11 минут
проблема решилась добавлением сгенерированных библиотек в

C:\Program Files (x86)\Borland\CBuilder6\Lib

все просто очень оказалось.
Может тема будет полезна ссылкой на пример клиент-сервер от майкрософт
0
 Аватар для cpp_developer
20124 / 5691 / 417
Регистрация: 09.04.2010
Сообщений: 22,546
Записей в блоге: 1
19.10.2011, 14:45
lizard, там про это тоже было:
укажите в настройках проекта - в Library Path путь к либе
0
 Аватар для lizard
0 / 0 / 0
Регистрация: 20.09.2011
Сообщений: 14
20.10.2011, 20:37  [ТС]
Что-то поэкспериментировав с кодом немного в ступор зашел.

Подскажите пожалуйста... данный код вообще является примером многопоточного сервера?


C++
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
#undef UNICODE
 
#define WIN32_LEAN_AND_MEAN
 
#include <windows.h>
#include <winsock2.h>
#include <ws2tcpip.h>
#include <stdlib.h>
#include <stdio.h>
 
// Need to link with Ws2_32.lib
#pragma comment (lib, "Ws2_32.lib")
// #pragma comment (lib, "Mswsock.lib")
 
#define DEFAULT_BUFLEN 512
#define DEFAULT_PORT "27015"
 
int __cdecl main(void) 
{
    WSADATA wsaData;
    int iResult;
 
    SOCKET ListenSocket = INVALID_SOCKET;
    SOCKET ClientSocket = INVALID_SOCKET;
 
    struct addrinfo *result = NULL;
    struct addrinfo hints;
 
    int iSendResult;
    char recvbuf[DEFAULT_BUFLEN];
    int recvbuflen = DEFAULT_BUFLEN;
    
    // Initialize Winsock
    iResult = WSAStartup(MAKEWORD(2,2), &wsaData);
    if (iResult != 0) {
        printf("WSAStartup failed with error: %d\n", iResult);
        return 1;
    }
 
    ZeroMemory(&hints, sizeof(hints));
    hints.ai_family = AF_INET;
    hints.ai_socktype = SOCK_STREAM;
    hints.ai_protocol = IPPROTO_TCP;
    hints.ai_flags = AI_PASSIVE;
 
    // Resolve the server address and port
    iResult = getaddrinfo(NULL, DEFAULT_PORT, &hints, &result);
    if ( iResult != 0 ) {
        printf("getaddrinfo failed with error: %d\n", iResult);
        WSACleanup();
        return 1;
    }
 
    // Create a SOCKET for connecting to server
    ListenSocket = socket(result->ai_family, result->ai_socktype, result->ai_protocol);
    if (ListenSocket == INVALID_SOCKET) {
        printf("socket failed with error: %ld\n", WSAGetLastError());
        freeaddrinfo(result);
        WSACleanup();
        return 1;
    }
 
    // Setup the TCP listening socket
    iResult = bind( ListenSocket, result->ai_addr, (int)result->ai_addrlen);
    if (iResult == SOCKET_ERROR) {
        printf("bind failed with error: %d\n", WSAGetLastError());
        freeaddrinfo(result);
        closesocket(ListenSocket);
        WSACleanup();
        return 1;
    }
 
    freeaddrinfo(result);
 
    iResult = listen(ListenSocket, SOMAXCONN);
    if (iResult == SOCKET_ERROR) {
        printf("listen failed with error: %d\n", WSAGetLastError());
        closesocket(ListenSocket);
        WSACleanup();
        return 1;
    }
 
    // Accept a client socket
    ClientSocket = accept(ListenSocket, NULL, NULL);
    if (ClientSocket == INVALID_SOCKET) {
        printf("accept failed with error: %d\n", WSAGetLastError());
        closesocket(ListenSocket);
        WSACleanup();
        return 1;
    }
 
    // No longer need server socket
    closesocket(ListenSocket);
 
    // Receive until the peer shuts down the connection
    do {
 
        iResult = recv(ClientSocket, recvbuf, recvbuflen, 0);
        if (iResult > 0) {
            printf("Bytes received: %d\n", iResult);
 
        // Echo the buffer back to the sender
            iSendResult = send( ClientSocket, recvbuf, iResult, 0 );
            if (iSendResult == SOCKET_ERROR) {
                printf("send failed with error: %d\n", WSAGetLastError());
                closesocket(ClientSocket);
                WSACleanup();
                return 1;
            }
            printf("Bytes sent: %d\n", iSendResult);
        }
        else if (iResult == 0)
            printf("Connection closing...\n");
        else  {
            printf("recv failed with error: %d\n", WSAGetLastError());
            closesocket(ClientSocket);
            WSACleanup();
            return 1;
        }
 
    } while (iResult > 0);
 
    // shutdown the connection since we're done
    iResult = shutdown(ClientSocket, SD_SEND);
    if (iResult == SOCKET_ERROR) {
        printf("shutdown failed with error: %d\n", WSAGetLastError());
        closesocket(ClientSocket);
        WSACleanup();
        return 1;
    }
 
    // cleanup
    closesocket(ClientSocket);
    WSACleanup();
 
    return 0;
}
0
17 / 16 / 1
Регистрация: 03.11.2009
Сообщений: 36
21.10.2011, 13:43
Нет. Вы создаете только один поток.

HTML5
1
http://cit*****.ru/book/cook/winsock.shtml
Почитайте
 Комментарий модератора 
Правила, п.3.7, увы ...
1
 Аватар для xAtom
935 / 760 / 299
Регистрация: 09.12.2010
Сообщений: 1,346
Записей в блоге: 1
22.10.2011, 12:07
Цитата Сообщение от lizard Посмотреть сообщение
Подскажите пожалуйста... данный код вообще является примером многопоточного сервера?
Многопоточностью здесь и не пахнет, это пример типа эхо-сервера на запрос ответ и сразу закрывается.
0
 Аватар для lizard
0 / 0 / 0
Регистрация: 20.09.2011
Сообщений: 14
28.10.2011, 02:09  [ТС]
Спасибо за ссылку, материал по ней дает первоначальное представление об использовании Winsock.

Есть еще вопрос:

Могу ли я самостоятельно определять структуру пакета, не используя RAW сокеты?
Может быть у кого нибудь есть ссылки по теме, идеально было бы с кодом откомменченым.

Добавлено через 12 часов 50 минут
Копнув глубже понял что RAW сокеты мне не нужны.
Есть проблема с передачей бинарных файлов.


C++
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
153
154
155
156
157
158
159
160
161
162
163
164
165
166
167
168
169
170
171
172
173
174
175
176
177
178
179
180
181
182
183
184
185
186
187
188
189
190
191
192
193
194
195
196
// server
 
  #include <stdafx.h>
  #include <stdio.h>
  #include <stdlib.h>
  #include <winsock2.h>
  #include <windows.h>
 
  #pragma comment (lib, "Ws2_32.lib")
  #define MY_PORT    20035
          
  #define PRINTNUSERS if (nclients)\
  printf("%d user on-line\n",nclients);\
  else printf("No User on line\n");
   
// new user service
  DWORD WINAPI SexToClient(LPVOID client_socket);
  
 
  void sendCommand (SOCKET socket, char *buffer)
  {
    
     int iResult = send(socket,buffer,(int)strlen(buffer),0);
     
     if (iResult == SOCKET_ERROR) {
        printf("send failed with error: %d\n", WSAGetLastError());
        closesocket(socket);
        WSACleanup();
        }
  }
 
  int sendFileSize(char *filename, SOCKET socket) {
    
      char buffer_sz[1024];
      FILE * pFile;
      long size;
 
  pFile = fopen (filename,"rb");
  if (pFile==NULL) {
      
      printf ("Error opening file"); 
      return 0;}
  else
  {
    fseek (pFile, 0, SEEK_END);
    size=ftell (pFile);
    itoa (size,buffer_sz,10);
    fclose (pFile);
  }
 
      sendCommand(socket, buffer_sz); 
}
 
  
  int sendFile(char *filename, SOCKET socket) {
  
      char buffer_sz[1024];
      FILE * pFile;
      long size;
 
  pFile = fopen (filename,"rb");
  if (pFile==NULL) {
      
      printf ("Error opening file"); 
      return 0;}
  else
  {
    fseek (pFile, 0, SEEK_END);
    size=ftell (pFile);
 
  }
 if(size == -1 || size == 0) {
        //sendCommand(socket, "111");
        return -1;
    }
 char tmp[1024];
    sprintf(tmp, "%i", size);
    sendCommand(socket, tmp);
     char* buffer;
    buffer = new char[size];
 
    fread(buffer, sizeof(buffer[0]), size, pFile);
    send(socket, buffer, size, 0);
 
    printf("%s", buffer);
 
    fclose(pFile);
    return 0;
 
 
  }
 
  int nclients = 0;
 
  int main(int argc, char* argv[])
  {
    char buff[1024];   
    
    printf("TCP SERVER\n");
 
    
    if (WSAStartup(0x0202,(WSADATA *) &buff[0])) 
    {
  
          printf("Error WSAStartup %d\n",
             WSAGetLastError());
      return -1;
    }
 
    SOCKET mysocket;
    
    if ((mysocket=socket(AF_INET,SOCK_STREAM,0))<0)
    {
    
      printf("Error socket %d\n",WSAGetLastError());
      WSACleanup();
      return -1;
    }
 
    sockaddr_in local_addr;
    local_addr.sin_family=AF_INET;
    local_addr.sin_port=htons(MY_PORT);
    local_addr.sin_addr.s_addr=0;
             
    if (bind(mysocket,(sockaddr *) &local_addr,
                sizeof(local_addr)))
    {
      
      printf("Error bind %d\n",WSAGetLastError());
      closesocket(mysocket); 
      WSACleanup();
      return -1;
    }
 
   // waiting for connect
 
    if (listen(mysocket, 0x100))
    {
     
      printf("Error listen %d\n",WSAGetLastError());
      closesocket(mysocket);
      WSACleanup();
      return -1;
    }
 
    printf("Waiting for connect\n");
 
    
    SOCKET client_socket;    
    sockaddr_in client_addr; 
     
    int client_addr_size=sizeof(client_addr);
 
   
    while((client_socket=accept(mysocket, (sockaddr *)  &client_addr, &client_addr_size)))
    {
      nclients++;      
      
      //host name obtaining
      HOSTENT *hst;
      hst=gethostbyaddr((char *)
          &client_addr.sin_addr.s_addr,4, AF_INET);
 
    
      printf("+%s [%s] new connect!\n",
      (hst)?hst->h_name:"",
      inet_ntoa(client_addr.sin_addr));
      PRINTNUSERS
 
     //thread for new client
     DWORD thID;
      CreateThread(NULL,NULL,SexToClient, &client_socket,NULL,&thID);
    }
    return 0;
  }
 
 
  DWORD WINAPI SexToClient(LPVOID client_socket)
  {
    SOCKET my_sock;
    FILE * pFile;
 
    my_sock=((SOCKET *) client_socket)[0];
    char buff[20*1024];
  
            //sendCommand(my_sock,buff);
            sendFileSize ("C:\\tmp\\client.exe", my_sock);
                      
    
  
    nclients--;
    printf("-disconnect\n"); PRINTNUSERS
 
    closesocket(my_sock);
    return 0;
  }
C++
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
// client
 
  #include "stdafx.h"
  #include <stdio.h>
  #include <string.h>
  #include <winsock2.h>
  #include <windows.h>
 
#pragma comment (lib, "Ws2_32.lib")
#pragma comment (lib, "Mswsock.lib")
#pragma comment (lib, "AdvApi32.lib")
 
  #define PORT 20035
  #define SERVERADDR "127.0.0.1"
 
    int recvResponse(SOCKET socket){
    
    char recvbuf[1024];
    int iResult;
  
    iResult = recv(socket,recvbuf,sizeof(recvbuf)-1,0);
    
    
    printf(recvbuf);
    return 0;
}
 
void recvFile(char *filename, SOCKET socket) {
    
      FILE *file = fopen(filename, "wb");
 
      int size = recvResponse(socket);
 
    char* buffer;
    buffer = new char[size];
 
    recv(socket, buffer, size, 0);
    
    fwrite( buffer, sizeof(buffer[0]), size, file);
      
    fclose(file);
}
 
  int main(int argc, char* argv[])
  {
    char buff[1024];
    printf("TCP DEMO CLIENT\n");
 
    if (WSAStartup(0x202,(WSADATA *)&buff[0]))
    {
      printf("WSAStart error %d\n",WSAGetLastError());
      return -1;
    }
    SOCKET my_sock;
    my_sock=socket(AF_INET,SOCK_STREAM,0);
    if (my_sock < 0)
    {
      printf("Socket() error %d\n",WSAGetLastError());
      return -1;
    }
 
    // server info
 
    sockaddr_in dest_addr;
    dest_addr.sin_family=AF_INET;
    dest_addr.sin_port=htons(PORT);
    HOSTENT *hst;
 
    if (inet_addr(SERVERADDR)!=INADDR_NONE)
      dest_addr.sin_addr.s_addr=inet_addr(SERVERADDR);
    else
    
      if (hst=gethostbyname(SERVERADDR))
      ((unsigned long *)&dest_addr.sin_addr)[0]=
        ((unsigned long **)hst->h_addr_list)[0][0];
      else 
      {
        printf("Invalid address %s\n",SERVERADDR);
        closesocket(my_sock);
        WSACleanup();
        return -1;
      }
  
      // try to connect
 
    if (connect(my_sock,(sockaddr *)&dest_addr, sizeof(dest_addr)))
    {
      printf("Connect error %d\n",WSAGetLastError());
      return -1;
    }
 
    printf("Success %s \n\ ",SERVERADDR);
 
    // Try to recieve file
 
    //  recvFile("D:\\tmp\\1.exe",my_sock);
    recvResponse(my_sock);
    
    system("pause");
      
      //scancl begin test
      //WinExec ( "C:\\avira\\scancl.exe D:\\tmp --log=D:\\log\\log.txt", SW_SHOWNORMAL );
 
 
    printf("Recv error %d\n",WSAGetLastError());
    closesocket(my_sock);
    WSACleanup();
    return -1;
  }

Ошибка при передаче размера файла. Буду рад любой помощи (:
0
290 / 193 / 23
Регистрация: 03.08.2011
Сообщений: 2,824
Записей в блоге: 12
29.10.2011, 12:35
lizard, "программирование игр на winsock" почитайте
0
 Аватар для lizard
0 / 0 / 0
Регистрация: 20.09.2011
Сообщений: 14
02.11.2011, 13:31  [ТС]
Немного дописал код, теперь возникает следующая ситуация:

Бинарный файл передается от сервера к клиенту, размер отправленного и переданного файла равны, однако при попытке запуска файла win7 64 выдает ошибку:

"Средству просмотра изображение не удалось открыть эту картинку, поскольку файл поврежден или слишком велик" - в случае jpg.
"Версия этого файла не совместима с используемой версией Windows..." - в случае exe.


C++
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
153
154
155
156
157
158
159
160
161
162
163
164
165
166
167
168
169
170
171
172
173
174
175
176
177
178
179
180
181
182
183
184
185
186
187
188
189
190
191
192
193
194
195
196
197
198
199
200
201
202
203
204
205
206
207
208
209
210
211
212
213
214
215
216
217
218
//server
#include <stdio.h>
#include "stdafx.h"
#include <iostream>
#include <fstream>
using namespace std;
  #include <winsock2.h>
  #include <windows.h>
 
#define DEFAULT_BUFLEN 512
#pragma comment (lib, "Ws2_32.lib")
  #define MY_PORT    20035
          
  #define PRINTNUSERS if (nclients)\
  printf("%d user on-line\n",nclients);\
  else printf("No User on line\n");
 
  DWORD WINAPI SexToClient(LPVOID client_socket);
  #define DEFAULT_BUFLEN 512
 
int getFileSize(FILE *sFile){
  
fseek( sFile, 0, SEEK_END );
int size = ftell( sFile );
fclose( sFile );
return size;
 
 }
 
  int sendFile (char *filename, SOCKET socket){
    
    char buffer[DEFAULT_BUFLEN], error_message[DEFAULT_BUFLEN];
    FILE *sFile;
    int file_size;
    int bytes_sent, byte_recieved;
    sFile= fopen(filename, "rb");
    if(sFile == NULL)
{
printf("Error opening file!");
}
    else{
file_size = getFileSize(sFile);
itoa(file_size, buffer, 10);
printf(buffer);
int bytes_sent = send(socket, buffer, (int)strlen(buffer), 0);
printf("\n Bytes sent: %d\n", bytes_sent);
while(file_size > 0)
{
fread(buffer, DEFAULT_BUFLEN, 1, sFile);
 
if((bytes_sent = send(socket, buffer, DEFAULT_BUFLEN, 0)) == SOCKET_ERROR)
{
itoa(WSAGetLastError(), error_message, 10);
 
strcat(error_message, " Error Sending file");
printf(error_message);
 
break;
 
}//End of if statement
 
file_size -= bytes_sent;
 
}//End of while loop
 
}//End of if/else statement
 
//Close the mp3 file
fclose(sFile);
 
//Wait for ack from client
while(!(recv(socket, buffer, DEFAULT_BUFLEN, 0)))
        ;
printf("success");
return 1;
    }
 
  int nclients = 0;
 
  int main(int argc, char* argv[])
  {
    char buff[1024];   
 
    printf("TCP SERVER DEMO\n");
 
    if (WSAStartup(0x0202,(WSADATA *) &buff[0])) 
    {
      
          printf("Error WSAStartup %d\n",
             WSAGetLastError());
      return -1;
    }
 
   
    SOCKET mysocket;
   
    if ((mysocket=socket(AF_INET,SOCK_STREAM,0))<0)
    {
 
      printf("Error socket %d\n",WSAGetLastError());
      WSACleanup();
       
      return -1;
    }
 
  
    sockaddr_in local_addr;
    local_addr.sin_family=AF_INET;
    local_addr.sin_port=htons(MY_PORT);
        
    local_addr.sin_addr.s_addr=0;
            
    if (bind(mysocket,(sockaddr *) &local_addr,
                sizeof(local_addr)))
    {
      
      printf("Error bind %d\n",WSAGetLastError());
      closesocket(mysocket); 
      WSACleanup();
      return -1;
    }
 
    
    if (listen(mysocket, 0x100))
    {
     
      printf("Error listen %d\n",WSAGetLastError());
      closesocket(mysocket);
      WSACleanup();
      return -1;
    }
 
    printf("waiting for connect\n");
 
    
    SOCKET client_socket;    
    sockaddr_in client_addr;    
            
 
    int client_addr_size=sizeof(client_addr);
 
  
    while((client_socket=accept(mysocket, (sockaddr *)
            &client_addr, &client_addr_size)))
    {
      nclients++;     
             
      HOSTENT *hst;
      hst=gethostbyaddr((char *)
          &client_addr.sin_addr.s_addr,4, AF_INET);
 
    
      printf("+%s [%s] new connect!\n",
      (hst)?hst->h_name:"",
      inet_ntoa(client_addr.sin_addr));
      PRINTNUSERS
 
   
      DWORD thID;
      CreateThread(NULL,NULL,SexToClient,
              &client_socket,NULL,&thID);
    }
    return 0;
  }
 
  
  DWORD WINAPI SexToClient(LPVOID client_socket)
  {
      SOCKET ClientSocket;
    ClientSocket=((SOCKET *) client_socket)[0];
    char buff[20*1024];
    #define sHELLO "Hello, Sailor\r\n"
     int iSendResult, iResult;
    char recvbuf[DEFAULT_BUFLEN];
    int recvbuflen = DEFAULT_BUFLEN;
 
    send(ClientSocket,sHELLO,sizeof(sHELLO),0);
 
   
      do {
 
    iResult=  recv(ClientSocket, recvbuf, sizeof(recvbuf),0);
 
 
    printf(recvbuf);
    
        if (iResult > 0) {
            printf("Bytes received: %d\n", iResult);
 
      
          iSendResult = sendFile("C:\\tmp\\1.jpg", ClientSocket);//send( ClientSocket, recvbuf, iResult, 0 );
            if (iSendResult == SOCKET_ERROR) {
                printf("send failed with error: %d\n", WSAGetLastError());
                closesocket(ClientSocket);
                WSACleanup();
                return 1;
            }
          
        }
        else if (iResult == 0)
            printf("Connection closing...\n");
        else  {
            printf("recv failed with error: %d\n", WSAGetLastError());
            closesocket(ClientSocket);
            WSACleanup();
            return 1;
        }}
        
      while( iResult>0    && iResult !=SOCKET_ERROR);
      
 
    nclients--; 
    printf("-disconnect\n"); PRINTNUSERS
 
   
    closesocket(ClientSocket);
    return 0;
  }
C++
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
//client  
  #include "stdafx.h"
  #include <stdio.h>
  #include <string.h>
  #include <winsock2.h>
  #include <windows.h>
 
#pragma comment (lib, "Ws2_32.lib")
  #define DEFAULT_BUFLEN 512
  #define PORT 20035
  #define SERVERADDR "127.0.0.1"
 
int recvFile(char *filename, SOCKET socket) {
    
    long file_size;
char buffer[DEFAULT_BUFLEN];
FILE *rFile;
int bytes_recieved, bytes_sent;
 
//Get the file size from the server
bytes_recieved = recv(socket, buffer, DEFAULT_BUFLEN, 0);
buffer[bytes_recieved] = '\0';
file_size = atoi(buffer);
 
rFile= fopen(filename, "wb");
 
 
//Get the file
while(file_size > 0)
{
bytes_recieved = recv(socket, buffer, DEFAULT_BUFLEN, 0);
fwrite(buffer, bytes_recieved, 1, rFile);
file_size -= (long)bytes_recieved;
//printf("File have been recieved");
}//End of while loop
 
//Close the file
fclose(rFile);
 
//Ack to the server that the file was transfered
if((bytes_sent = send(socket, "1", 1, 0)) == SOCKET_ERROR)
{
 
printf("Error Recieving file");
return 0;
 
}//End of if statement
 
return 1;
}
 
  int main(int argc, char* argv[])
  {
    char buff[1024];
    printf("TCP DEMO CLIENT\n");
    if (WSAStartup(0x202,(WSADATA *)&buff[0]))
    {
      printf("WSAStart error %d\n",WSAGetLastError());
      return -1;
    }
 
   
    SOCKET my_sock;
    my_sock=socket(AF_INET,SOCK_STREAM,0);
    if (my_sock < 0)
    {
      printf("Socket() error %d\n",WSAGetLastError());
      return -1;
    }
 
   
    sockaddr_in dest_addr;
    dest_addr.sin_family=AF_INET;
    dest_addr.sin_port=htons(PORT);
    HOSTENT *hst;
 
   
    if (inet_addr(SERVERADDR)!=INADDR_NONE)
      dest_addr.sin_addr.s_addr=inet_addr(SERVERADDR);
    else
     
      if (hst=gethostbyname(SERVERADDR))
    
      ((unsigned long *)&dest_addr.sin_addr)[0]=
        ((unsigned long **)hst->h_addr_list)[0][0];
      else 
      {
        printf("Invalid address %s\n",SERVERADDR);
        closesocket(my_sock);
        WSACleanup();
        return -1;
      }
 
  
    if (connect(my_sock,(sockaddr *)&dest_addr,
                sizeof(dest_addr)))
    {
      printf("Connect error %d\n",WSAGetLastError());
      return -1;
    }
 
    printf("successful connect with %s \n\
    Type quit for quit\n\n",SERVERADDR);
 
   
     int nsize;
    while((nsize=recv(my_sock,&buff[0], sizeof(buff)-1,0)) !=SOCKET_ERROR)
    {
     
        
      buff[nsize]='\0';
 
      printf("S<=C:"); fgets(&buff[0],sizeof(buff)-1,
             stdin);
 
      if (!strcmp(&buff[0],"quit\n"))
      {
       
        printf("Exit...");
        closesocket(my_sock);
        WSACleanup();
        return 0;
        
      }
 
      send(my_sock,&buff[0],nsize,0);
      recvFile("D:\\tmp\\2.jpg", my_sock);
    }
 
    printf("Recv error %d\n",WSAGetLastError());
    closesocket(my_sock);
    WSACleanup();
    return -1;
  }

Подскажите, пожалуйста, в чем проблема. И правильна ли вообще логика.

Так же интересует вопрос формирования структуры буфера (к примеру мне надо сделать шапку таблицы MD5, size, info и засунуть туда несколько файлов) что для этого надо использовать, может у кого есть полезные линки.



Буду рад подсказкам\помощи (:
0
290 / 193 / 23
Регистрация: 03.08.2011
Сообщений: 2,824
Записей в блоге: 12
02.11.2011, 14:21
1считываете файл полностью в очеь большую строку
2проверьте в неё наличие символов при которых функция send прикращает свою работу символ 0 или eof должен быть только в конце строки
3 вызовите функцию send в циклке так как одна send естественно файл не передаст
4 вызовите функцию recv в цикле
5 создайте файл с нужным расширение
6заппишите в него строку
0
Надоела реклама? Зарегистрируйтесь и она исчезнет полностью.
inter-admin
Эксперт
29715 / 6470 / 2152
Регистрация: 06.03.2009
Сообщений: 28,500
Блог
02.11.2011, 14:21
Помогаю со студенческими работами здесь

Многопоточный TCP сервер
Здравствуйте. Хочу реализовать САБЖ. Сделал сервер, слушающий порт, и передающий дискриптор входящего соединения потоку. В потоке создается...

Многопоточный сервер TCP: разослать сообщения по всем клиентам
Есть tcp сервер, который принимает данные от клиентов и выводит в консоль, и дает ответ клиенту. Уже сутки не могу решить одну...

Как написать многопоточный tcp сервер, рассчитанный на множество подключений
Всем привет, подскажите как написать tcp сервер, на tcp сокетах, к которому постоянно буду пытаться подключится много клиентов, но сервер...

Многопоточный TCP client (QThread и QTcpSocket)
Здравствуйте. Вот в очередной раз столкнулся с проблемой... Есть TCP сокет сервера (adress и port) - с которого раз в 0.5 сек нужно...

Если сервер TCP то и клиент тоже должен быть TCP?
Я полный новичок И я так понимаю есть TCP client (Sockets), TCP server (Sockets), и ClientSocket (ScktComp), ServerSocket (ScktComp) ...


Искать еще темы с ответами

Или воспользуйтесь поиском по форуму:
11
Ответ Создать тему
Новые блоги и статьи
Изучаю kubernetes
lagorue 13.01.2026
А пригодятся-ли мне знания kubernetes в России?
Сукцессия микоризы: основная теория в виде двух уравнений.
anaschu 11.01.2026
https:/ / rutube. ru/ video/ 7a537f578d808e67a3c6fd818a44a5c4/
WordPad для Windows 11
Jel 10.01.2026
WordPad для Windows 11 — это приложение, которое восстанавливает классический текстовый редактор WordPad в операционной системе Windows 11. После того как Microsoft исключила WordPad из. . .
Classic Notepad for Windows 11
Jel 10.01.2026
Old Classic Notepad for Windows 11 Приложение для Windows 11, позволяющее пользователям вернуть классическую версию текстового редактора «Блокнот» из Windows 10. Программа предоставляет более. . .
Почему дизайн решает?
Neotwalker 09.01.2026
В современном мире, где конкуренция за внимание потребителя достигла пика, дизайн становится мощным инструментом для успеха бренда. Это не просто красивый внешний вид продукта или сайта — это. . .
Модель микоризы: классовый агентный подход 3
anaschu 06.01.2026
aa0a7f55b50dd51c5ec569d2d10c54f6/ O1rJuneU_ls https:/ / vkvideo. ru/ video-115721503_456239114
Owen Logic: О недопустимости использования связки «аналоговый ПИД» + RegKZR
ФедосеевПавел 06.01.2026
Owen Logic: О недопустимости использования связки «аналоговый ПИД» + RegKZR ВВЕДЕНИЕ Введу сокращения: аналоговый ПИД — ПИД регулятор с управляющим выходом в виде числа в диапазоне от 0% до. . .
Модель микоризы: классовый агентный подход 2
anaschu 06.01.2026
репозиторий https:/ / github. com/ shumilovas/ fungi ветка по-частям. коммит Create переделка под биомассу. txt вход sc, но sm считается внутри мицелия. кстати, обьем тоже должен там считаться. . . .
КиберФорум - форум программистов, компьютерный форум, программирование
Powered by vBulletin
Copyright ©2000 - 2026, CyberForum.ru