[英]Winsock send () over TCP in C
我只是在Winsock中使用send()函數而感到困惑。 該代碼實際上是否通過TCP發送字符串“ Hello”? 我設法在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;
}
}
您的代碼沒有初始化WinSock,沒有分配任何SOCKET
對象,並且沒有在調用send()
之前在套接字和對等方之間建立連接,因此可以回答您的問題:
否 ,您的代碼未通過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;
}
不,它不發送字符串“ Hello”。 即使套接字綁定/接受/等連接正常,也可以發送“ send(client_socket,sendbuf,strlen(sendbuf),0);” 不發送C字符串。 它發送五個字節,而C字符串“ Hello”需要六個字節。 嘗試:
send(client_socket,sendbuf,1 + strlen(sendbuf),0);
通過在源文本中搜索“ strlen”,可以發現很高比例的網絡C代碼問題。 printf(%s ..),並假設TCP傳輸的消息長度超過一個字節,其余的原因:
聲明:本站的技術帖子網頁,遵循CC BY-SA 4.0協議,如果您需要轉載,請注明本站網址或者原文地址。任何問題請咨詢:yoyou2525@163.com.