Наши проекты:
Журнал · Discuz!ML · Wiki · DRKB · Помощь проекту |
||
ПРАВИЛА | FAQ | Помощь | Поиск | Участники | Календарь | Избранное | RSS |
[18.97.14.84] |
|
Сообщ.
#1
,
|
|
|
У меня почему-то происходит потеря части информации, причём когда я тестю дома(с своего ПК на свой, указывая свой локальный ip=10.3.5.58 и какой-нить порт) то всё отлично передаётся, а когда я прихожу в универ и такое-же пытаюсь провернють там то файл присылается несклько меньше чем должен быть(так же со своего ПК на свой), в чём могут быть пробледы, могут ли по TCP теряться данные и должен ли я за этим следить? Кому не сложно вот код.
Сервер #include <stdio.h> #include "winsock2.h" #define BUFF 32 #define MAX_SLEEP 1 void start_server( char* hostname, unsigned short hostsocket ) { // Initialize Winsock. WSADATA wsaData; //MAKEWORD(2,2) загрузка dll версии > 2,2 int iResult = WSAStartup( MAKEWORD(2,2), &wsaData ); if ( iResult != NO_ERROR ) printf("Error at WSAStartup()\n"); // Create a socket. SOCKET m_socket; //Что за сокет m_socket = socket( AF_INET, SOCK_STREAM, IPPROTO_TCP ); if ( m_socket == INVALID_SOCKET ) { printf( "Error at socket(): %ld\n", WSAGetLastError() ); WSACleanup(); return; } // Bind the socket. sockaddr_in service; service.sin_family = AF_INET; service.sin_addr.s_addr = inet_addr( hostname ); service.sin_port = htons( hostsocket ); if ( bind( m_socket, (SOCKADDR*) &service, sizeof(service) ) == SOCKET_ERROR ) { printf( "bind() failed.\n" ); printf( ": %ld\n", WSAGetLastError() ); closesocket(m_socket); return; } // Listen on the socket. if ( listen( m_socket, 1 ) == SOCKET_ERROR ) printf( "Error listening on socket.\n"); // Accept connections. SOCKET AcceptSocket; printf( "Waiting for a client to connect...\n" ); AcceptSocket = SOCKET_ERROR; while ( AcceptSocket == SOCKET_ERROR ) { AcceptSocket = accept( m_socket, NULL, NULL ); } printf( "Client Connected.\n"); m_socket = AcceptSocket; // Send and receive data. int bytesRecv; long totalSize = 0; int k = 0; char recvbuf[32]; char bufsend[1] = {'9'}; char name[100]; char ch; // Вытаскиваем имя файла с сокета. до первого '\0' bytesRecv = recv( m_socket, &ch, 1, 0 ); while (bytesRecv >= 0 && ch != '\0'){ name[k++] = ch; bytesRecv = recv( m_socket, &ch, 1, 0 ); } name[k] = ch; long* p = (long* )malloc(sizeof(long)); // Отправляем размер файла. if ( recv( m_socket, (char* )p, sizeof(long), 0 ) != sizeof(long) ){ printf("Filename not sent."); return; } long sizeOfFile = *p; // Создаём файл в который пишим всё с сокета. FILE* fp = fopen(name, "wb"); if (fp == NULL) return; printf("Size of file: %ld\n", sizeOfFile); int tmp = sizeOfFile; boolean j = false; // Получаем всё что нам отправленно. while (1){ bytesRecv = recv(m_socket, recvbuf, BUFF, 0); if ( sizeOfFile == 0 && bytesRecv <= 0 ) { break; } else if ( bytesRecv <= 0 ) { if ( j == false ) { Sleep(MAX_SLEEP); j = true; } else { printf ("Exclusive exit by timeout: recive only %ld", tmp - sizeOfFile); exit(1); } continue; } else { fwrite((void* )recvbuf, bytesRecv, 1, fp); sizeOfFile -= (long)bytesRecv; j = false; } } printf( "Connection closed, after receiving all %d bytes\n", tmp); fclose(fp); return; } void main(int argc, char* argv[]) { if ( argc == 3 ) { start_server( argv[1], (unsigned short) atoi(argv[2]) ); } else { printf("Used: cmd/> server.exe <host> <port>"); } } Клиент #include <stdio.h> #include "winsock2.h" #define BUFF 32 void start_client( char* hostname, unsigned short hostsocket, char* filename ) { FILE* fp = fopen( filename, "rb" ); if ( fp == NULL ) return; // Initialize Winsock. WSADATA wsaData; int iResult = WSAStartup( MAKEWORD(2,2), &wsaData ); if ( iResult != NO_ERROR ) printf("Error at WSAStartup()\n"); // Create a socket. SOCKET m_socket; m_socket = socket( AF_INET, SOCK_STREAM, IPPROTO_TCP ); if ( m_socket == INVALID_SOCKET ) { printf( "Error at socket(): %ld\n", WSAGetLastError() ); WSACleanup(); return; } // Connect to a server. sockaddr_in clientService; clientService.sin_family = AF_INET; clientService.sin_addr.s_addr = inet_addr( hostname ); clientService.sin_port = htons( hostsocket ); if ( connect( m_socket, (SOCKADDR*) &clientService, sizeof(clientService) ) == SOCKET_ERROR) { printf( "Failed to connect.\n" ); WSACleanup(); return; } // Send and receive data. char sendbuf[BUFF]; char recvbuf[1] = {'9'}; int bytesSent; int size; // Отправляем имя файла + '\0' if ( send( m_socket, filename, (int)strlen(filename) + 1, 0 ) <= 0 ){ printf("Filename not sent."); return; } fseek(fp, 0, SEEK_END); //void* array = (void* )((int)ftell(fp)); long f = ftell(fp); long* p; p = &f; fseek(fp, 0, SEEK_SET); // Отправляем размер файла. if ( send( m_socket, (char* )p, sizeof(long), 0 ) <= 0 ){ printf("Filename not sent."); return; } printf("To server connected."); // Отправляем содержимое файла. size = (int)fread( (void *) sendbuf, sizeof(char), BUFF, fp ); while ( !feof(fp) ) { bytesSent = send( m_socket, sendbuf, size, 0 ); while ( recv( m_socket, recvbuf, 1, 0 ) == 0 ) {int i = 0; i++; printf("%c", recvbuf[1]);} if ( size - bytesSent == 0 ) size = (int)fread( (void* ) sendbuf, sizeof(char), BUFF, fp ); } bytesSent = send( m_socket, sendbuf, size, 0 ); return; } void main ( int argc, char* argv[] ) { if ( argc == 4 ) start_client( argv[1], (unsigned short) atoi(argv[2]), argv[3] ); else printf("Used: cmd/> client.exe <host> <port> <filename>"); } |
Сообщ.
#2
,
|
|
|
Сообщ.
#3
,
|
|
|
bestbrocker
Цитата if ( listen( m_socket, 1 ) == SOCKET_ERROR ) Нельзя устанавливать очередь в 1 - минимум 5! listen( m_socket, 5 ) |
Сообщ.
#4
,
|
|
|
Цитата Oleg2004 @ Нельзя устанавливать очередь в 1 - минимум 5! почему это?? есть максимум , а минимума нет.. |
Сообщ.
#5
,
|
|
|
У. Стивенс:
Цитата Для TCP-сервера функция listen() формирует в ядре системы два вида буферов: · Буфер-очередь не полностью установленных соединений (т.е. тех, для которых идет и еще полностью не завершен трехсторонний handshake); · Буфер-очередь полностью установленных соединений (т.е. тех, для которых трехсторонний handshake успешно завершен и сервер принимает конкретный запрос на обслуживание). · Сумма длин обеих очередей не может превышать значение backlog, поэтому ее указание как 1 позволит только установить соединение, но не принимать данные по нему (очередь будет полна). |