2014-01-10 116 views
0

我只是在Winsock中使用send()函數而感到困惑。這段代碼是否實際上通過TCP發送了一個字符串「Hello」?我設法在LabVIEW中與TCP客戶端建立連接,但似乎這個TCP服務器不發送任何東西。Winsock通過TCP在C發送()

#define DEFAULT_BUFLEN 1024 

#include<stdio.h> 
#include<winsock2.h> 
#include<Ws2tcpip.h> 
#include<stdlib.h> 
#include<string.h> 
#include<stdint.h> 
#include<stddef.h> 

#pragma comment(lib,"ws2_32.lib") //Winsock Library 

int main(int argc , char *argv[]) 
{ 
WSADATA wsa; 
SOCKET s , new_socket; 
struct sockaddr_in server , client; 
int c; 
int iResult; 
char *sendbuf = "Hello"; 


printf("\nInitialising Winsock..."); 
if (WSAStartup(MAKEWORD(2,2),&wsa) != 0) 
    { 
    printf("Failed. Error Code : %d",WSAGetLastError()); 
    return 1; 
    } 

printf("Initialised.\n"); 

//Create a socket 
if((s = socket(AF_INET , SOCK_STREAM , 0)) == INVALID_SOCKET) 
    { 
    printf("Could not create socket : %d" , WSAGetLastError()); 
    } 

printf("Socket created.\n"); 

//Prepare the sockaddr_in structure 
server.sin_family = AF_INET; 
server.sin_addr.s_addr = INADDR_ANY; 
server.sin_port = htons(13000); 

//Bind 
if(bind(s ,(struct sockaddr *)&server , sizeof(server)) == SOCKET_ERROR) 
    { 
    printf("Bind failed with error code : %d" , WSAGetLastError()); 
    } 

puts("Bind done"); 

//Listen to incoming connections 
listen(s , 3); 

//Accept and incoming connection 
puts("Waiting for incoming connections..."); 

c = sizeof(struct sockaddr_in); 
new_socket = accept(s , (struct sockaddr *)&client, &c); 
if (new_socket == INVALID_SOCKET) 
    { 
    printf("accept failed with error code : %d" , WSAGetLastError()); 
    } 

iResult = send(new_socket, sendbuf, (int)strlen(sendbuf), 0); 

if (iResult == SOCKET_ERROR) 
{ 
    wprintf(L"send failed with error: %d\n", WSAGetLastError()); 
    closesocket(new_socket); 
    WSACleanup(); 
    return 1; 
} 
printf("Bytes Sent: %d\n", iResult); 

// shutdown the connection since no more data will be sent 
iResult = shutdown(new_socket, SD_SEND); 
if (iResult == SOCKET_ERROR) 
    { 
    wprintf(L"shutdown failed with error: %d\n", WSAGetLastError()); 
    closesocket(new_socket); 
    WSACleanup(); 
    return 1; 
    } 
} 
+1

那麼爲什麼只是不檢查它呢? –

+0

http://msdn.microsoft.com/en-us/library/windows/desktop/ms740149%28v=vs.85%29.aspx –

+1

也是你的套接字沒有連接,所以它會發送到哪裏? –

回答

3

你的代碼不initialzing的WinSock,沒有分配任何SOCKET對象,並調用send()之前未建立socket和服務器之間的連接,所以回答你的問題:

NO,你代碼不通過TCP發送字符串。

無論其,如果你遺漏的部分補 - 呼叫socket()創建TCP套接字,並調用bind()/listen()/accept()建立與對等TCP連接 - 然後,你的代碼將被髮送通過TCP串。

您需要做的更像下面的內容。這只是一個簡單的例子,它建立了一個TCP連接,然後一旦字符串被髮送到客戶端就退出。在現實世界的應用程序,你需要離開服務器套接字開放,不斷打電話accept(),如果你想服務隨着時間的推移多個客戶端連接,即使只是一個單一的客戶端曾經連接,斷開連接,並重新連接:

int main(int argc , char *argv[]) 
{ 
    WSADATA wsa; 
    SOCKET server_socket, client_socket; 
    struct sockaddr_in server_addr, client_addr; 
    int iResult; 
    char *sendbuf = "Hello"; 

    iResult = WSAStartup(MAKEWORD(2, 0), &wsa); 
    if (iResult != 0) 
    { 
     wprintf(L"WinSock startup failed with error: %d\n", iResult); 
     return 1; 
    } 

    server_socket = socket(AF_INET, SOCK_STREAM, IPPROTO_TCP); 
    if (server_socket == INVALID_SOCKET) 
    { 
     wprintf(L"socket failed with error: %d\n", WSAGetLastError()); 
     WSACleanup(); 
     return 1; 
    } 

    memset(&server_addr, 0, sizeof(server_addr); 
    server_addr.sin_family = AF_INET; 
    server_addr.sin_port = htons(some port number here); 
    server_addr.sin_addr.s_addr = INADDR_ANY; 

    if (bind(server_socket, (sockaddr*)&server_addr, sizeof(server_addr)) != 0) 
    { 
     wprintf(L"bind failed with error: %d\n", WSAGetLastError()); 
     closesocket(server_socket); 
     WSACleanup(); 
     return 1; 
    } 

    if (listen(server_socket, 1) != 0) 
    { 
     wprintf(L"listen failed with error: %d\n", WSAGetLastError()); 
     closesocket(server_socket); 
     WSACleanup(); 
     return 1; 
    } 

    iResult = sizeof(client_addr); 
    client_socket = accept(server_socket, (sockaddr*)&client_addr, &iResult); 
    if (client_socket == SOCKET_ERROR) 
    { 
     wprintf(L"accept failed with error: %d\n", WSAGetLastError()); 
     closesocket(server_socket); 
     WSACleanup(); 
     return 1; 
    } 

    closesocket(server_socket); 

    iResult = send(client_socket, sendbuf, strlen(sendbuf), 0); 
    if (iResult == SOCKET_ERROR) 
    { 
     wprintf(L"send failed with error: %d\n", WSAGetLastError()); 
     closesocket(client_socket); 
     WSACleanup(); 
     return 1; 
    } 

    printf("Bytes Sent: %d\n", iResult); 

    closesocket(client_socket); 
    WSACleanup(); 
    return 0; 
} 

更新:根據您更新的代碼,試試這個:

#include <stdio.h> 
#include <winsock2.h> 
#include <Ws2tcpip.h> 
#include <stdlib.h> 
#include <string.h> 
#include <stdint.h> 
#include <stddef.h> 

#pragma comment(lib, "ws2_32.lib") //Winsock Library 

int main(int argc , char *argv[]) 
{ 
    WSADATA wsa; 
    SOCKET server_socket, client_socket; 
    struct sockaddr_in server_addr, client_addr; 
    int c, iResult; 
    char *sendbuf = "Hello"; 

    printf("Initializing Winsock...\n"); 

    iResult = WSAStartup(MAKEWORD(2,2), &wsa); 
    if (iResult != 0) 
    { 
     printf("WinSock initialization Failed. Error Code : %d", iResult); 
     return 1; 
    } 

    printf("WinSock Initialized.\n"); 

    //Create a socket 
    s = socket(AF_INET, SOCK_STREAM, IPPROTO_TCP); 
    if (s == INVALID_SOCKET) 
    { 
     printf("Could not create socket. Error Code : %d" , WSAGetLastError()); 
     WSACleanup(); 
     return 1; 
    } 

    printf("Socket created.\n"); 

    //Prepare the sockaddr_in structure 
    memset(&server_addr, 0, sizeof(server_addr)); 
    server_addr.sin_family = AF_INET; 
    server_addr.sin_addr.s_addr = INADDR_ANY; 
    server_addr.sin_port = htons(13000); 

    //Bind the listening port 
    if (bind(server_socket, (struct sockaddr *)&server_addr, sizeof(server_addr)) == SOCKET_ERROR) 
    { 
     printf("Bind failed. Error Code : %d", WSAGetLastError()); 
     closesocket(server_socket); 
     WSACleanup(); 
     return 1; 
    } 

    printf("Socket bound to port 13000.\n"); 

    //Listen to incoming connection 
    if (listen(server_socket, 1) == SOCKET_ERROR) 
    { 
     printf("Listen failed. Error Code : %d", WSAGetLastError()); 
     closesocket(server_socket); 
     WSACleanup(); 
     return 1; 
    } 

    //Accept an incoming connection 
    printf("Waiting for incoming connection...\n"); 

    c = sizeof(client_addr); 
    client_socket = accept(server_socket, (struct sockaddr *)&client_addr, &c); 
    if (client_socket == INVALID_SOCKET) 
    { 
     printf("Accept failed. Error Code : %d", WSAGetLastError()); 
     closesocket(server_socket); 
     WSACleanup(); 
     return 1; 
    } 

    printf("Client connected from %s:%hu\n", inet_ntoa(client_addr.sin_addr), ntohs(client_addr.sin_port)); 

    //Stop accepting incoming connections 
    closesocket(server_socket); 

    // Send string to client 
    iResult = send(client_socket, sendbuf, strlen(sendbuf), 0); 
    if (iResult == SOCKET_ERROR) 
    { 
     printf("Send failed. Error Code : %d\n", WSAGetLastError()); 
     iResult = 1; 
    } 
    else 
    { 
     printf("Bytes Sent: %d\n", iResult); 
     iResult = 0; 
    } 

    // shutdown the connection since no more data will be sent 
    if (shutdown(client_socket, SD_SEND) == SOCKET_ERROR) 
    { 
     printf("Shutdown failed. Error Code : %d\n", WSAGetLastError()); 
     iResult = 1; 
    } 

    closesocket(client_socket); 
    WSACleanup(); 

    return iResult; 
} 
1

不,它不會發送字符串 「Hello」。即使套接字bind/accept/etc連接正常,'send(client_socket,sendbuf,strlen(sendbuf),0);'不發送C字符串。它發送5個字節,而C字符串「Hello」需要6個字節。嘗試:

send(client_socket,sendbuf,1 + strlen(sendbuf),0);

通過在源文本中搜索'strlen',可以找到非常高比例的網絡C代碼問題。 printf(%s ..),並假設TCP傳輸的消息長於一個字節,佔其他:)

+0

嗨發送一個字符串的問題。我只是想知道如何知道字符串「Hello」需要六個字節? –