简体   繁体   English

Winsock通过C中的TCP发送()

[英]Winsock send () over TCP in C

I'm just confusing using the send() function in Winsock. 我只是在Winsock中使用send()函数而感到困惑。 Does this code actually send a string "Hello" over TCP ?. 该代码实际上是否通过TCP发送字符串“ Hello”? I managed to establish a connection with a TCP client in LabVIEW but it seems like that this TCP server doesn't send anything. 我设法在LabVIEW中与TCP客户端建立连接,但似乎该TCP服务器未发送任何内容。

#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;
  }
}

Your code is not initialzing WinSock, not allocating any SOCKET object, and not establishing a connection between the socket and a peer before calling send() , so to answer your question: 您的代码没有初始化WinSock,没有分配任何SOCKET对象,并且没有在调用send()之前在套接字和对等方之间建立连接,因此可以回答您的问题:

NO , your code is NOT sending a string over TCP. ,您的代码未通过TCP发送字符串。

HOWEVER , if you fill in the missing pieces - call socket() to create a TCP socket, and call bind()/listen()/accept() to establish a TCP connection with a peer - then YES , your code will be sending the string over TCP. 但是 ,如果您填写缺少的部分-调用socket()创建一个TCP套接字,并调用bind()/listen()/accept()建立与对等方的TCP连接-然后 ,您的代码将被发送TCP上的字符串。

You need to do something more like the following instead. 您需要执行以下类似的操作。 This is just a simple example that establishes a single TCP connection and then exits once the string has been sent to the client. 这只是一个简单的示例,该示例建立单个TCP连接,然后在将字符串发送到客户端后退出。 In a real-world application, you would need to leave the server socket open and continuously calling accept() if you want to service multiple client connections over time, even if just a single client ever connects, disconnects, and reconnects: 在实际的应用程序中,如果您想随着时间的推移为多个客户端连接提供服务,则即使只有一个客户端进行连接,断开连接和重新连接,也需要保持服务器套接字打开并连续调用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;
}

Update : based on your updated code, try this: 更新 :根据您更新的代码,尝试以下操作:

#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;
} 

No, it does not send the string "Hello". 不,它不发送字符串“ Hello”。 Even if the socket bind/accept/etc connection is OK, 'send(client_socket, sendbuf, strlen(sendbuf), 0);' 即使套接字绑定/接受/等连接正常,也可以发送“ send(client_socket,sendbuf,strlen(sendbuf),0);” does not send a C string. 不发送C字符串。 It sends five bytes, whereas the the C string "Hello" requires six bytes. 它发送五个字节,而C字符串“ Hello”需要六个字节。 Try: 尝试:

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

A very high percentage of networking C code problems can be found by searching the source text for 'strlen'. 通过在源文本中搜索“ strlen”,可以发现很高比例的网络C代码问题。 printf(%s..), and assuming that TCP transfers messages longer than one byte, accounts for the rest:) printf(%s ..),并假设TCP传输的消息长度超过一个字节,其余的原因:

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM