在 windows 上进行 C 套接字编程时,我需要替换哪些等效的 headers、函数和数据类型?
Which equivalent headers, functions, and data types do I need to replace while doing C socket programming on windows?
最近开始接触C socket编程。经过几天的学习,我写了这个程序,它监听特定 IP 和端口上的连接:
#include <stdio.h>
#include <sys/types.h>
#include <sys/socket.h>
#include <netinet/in.h>
#include <stdlib.h>
#include <string.h>
#include <unistd.h>
#include <arpa/inet.h>
int main()
{
printf ("The program has started\n");
int sock, client_socket;
char buffer[1024];
char response[1024];
struct sockaddr_in server_address, client_address;
int i = 0;
int optval = 1;
socklen_t client_length;
sock = socket(AF_INET, SOCK_STREAM, 0);
if (setsockopt(sock, SOL_SOCKET, SO_REUSEADDR, &optval, sizeof(optval)) < 0)
{
printf("Error setting TCP socket options!\n");
return 1;
}
else {
printf ("TCP socket set successfully!\n");
}
server_address.sin_family = AF_INET;
server_address.sin_addr.s_addr = inet_addr("10.0.2.15");
server_address.sin_port = htons(5005);
int stat_check = bind (sock, (struct sockaddr*) &server_address, sizeof (server_address));
if (stat_check != 0)
{
printf ("Couldn't bind\n");
}
else {
printf ("binded successfully\n");
}
stat_check = listen(sock, 5);
if (!(stat_check == 0))
{
printf ("Failed to listen!\n");
}
else {
printf ("Listening...\n");
}
printf ("now the program will attempt to accept the connectionHSHA\n");
client_length = sizeof(client_address);
client_socket = accept (sock, (struct sockaddr*) &client_address, &client_length);
printf ("Socket Accepted or something happened\n");
if (client_socket == -1)
{
printf ("Couldn't accept connection!\n");
}
else
{
printf ("Connection Accepted!\n");
}
while (1)
{
jump:
bzero(&buffer, sizeof(buffer));
bzero(&response, sizeof(response));
printf("* Shell#%s~$: ", inet_ntoa(client_address.sin_addr));
fgets(buffer, sizeof(buffer), stdin);
strtok(buffer, "\n");
write(client_socket, buffer, sizeof(buffer));
if (strncmp("q", buffer, 1) == 0)
{
break;
}
else
{
recv(client_socket, response, sizeof(response), MSG_WAITALL);
printf("%s", response);
}
}
}
此程序在我的 Linux 系统中编译 100% 正常,但我需要它 运行 在 windows 上。当我使用 MinGW 编译器在我的 windows 上编译同一个程序时,它 运行 出现许多 missing-header 错误。不过windows里面有一些socket编程的库,比如winsock.h
。但是,当我将 winsock.h
替换为 <sys/socket>
并删除其他 Linux 库(arpa/inet.h
等)时,仍然会出现一些其他错误,例如 socklen_t undefined
。我也收到了一些警告。
总而言之,如果我想 运行 windows 上的这段代码,我不清楚我需要替换哪些等效的库、函数和数据类型。或者我可以用任何其他方式 运行 它在 windows 上吗?任何建议将不胜感激。
谢谢!
这是一个简单但完整的服务器示例,该示例使用 Windows 下的套接字为 TCP 提供服务。
它接受多个并发客户端并用一个线程为它们服务。
服务器接受来自每个客户端的命令行并在服务器端回显它们(通过简单的发送很容易回显给客户端)。如果命令是“退出”,则服务器关闭连接。
当然还有很多改进的空间。你有想法...
#include <stdio.h>
#include <stdlib.h>
#include <sys/types.h>
#include <WinSock2.h>
#define portNo 2100
#define MAX_CLIENTS 10
struct clientData {
int busy;
int inSocket;
HANDLE hThread;
DWORD threadId;
};
struct clientData cliArray[MAX_CLIENTS];
int cliCount;
DWORD WINAPI ClientThreadFunction(LPVOID lpParam)
{
struct clientData* cliData = (struct clientData*)lpParam;
printf("[%d] Client start. Socket=%d\n", cliData->inSocket, cliData->inSocket);
char buf[1024];
int rcvLen;
int rcvCount = 0;
char ch;
while (1) {
rcvLen = recv(cliData->inSocket, &ch, 1, 0);
if (rcvLen <= 0)
break;
if (ch == '\r')
continue; // Ignore return character (followed by '\n')
if (ch != '\n') {
putchar(ch);
buf[rcvCount++] = ch;
buf[rcvCount] = 0; // nul terminate string
}
else {
printf("\n[%d] Line=\"%s\"\n", cliData->inSocket, buf);
if (_stricmp(buf, "exit") == 0)
break;
rcvCount = 0;
buf[0] = 0;
}
}
closesocket(cliData->inSocket);
printf("[%d] Client terminated.\n", cliData->inSocket);
cliData->busy = 0;
return 1;
}
int main(int argc, char *argv[])
{
int iResult;
WSADATA wsaData;
// Initialize Winsock
iResult = WSAStartup(MAKEWORD(2, 2), &wsaData);
if (iResult != 0) {
printf("WSAStartup failed: %d\n", iResult);
return 1;
}
int srvSocket = socket(AF_INET, SOCK_STREAM, IPPROTO_TCP);
if (srvSocket < 0) {
fprintf(stderr, "Open socket failed with error %d\n", WSAGetLastError());
return 1;
}
struct sockaddr_in sockAddr;
memset(&sockAddr, 0, sizeof(sockAddr));
sockAddr.sin_family = AF_INET;
sockAddr.sin_port = htons(portNo);
sockAddr.sin_addr.s_addr = INADDR_ANY;
if (bind(srvSocket, (struct sockaddr*)&sockAddr, sizeof(sockAddr))) {
fprintf(stderr, "bind socket failed with error %d\n", WSAGetLastError());
closesocket(srvSocket);
WSACleanup();
return 1;
}
if (listen(srvSocket, 5)) {
fprintf(stderr, "listen socket failed with error %d\n", WSAGetLastError());
closesocket(srvSocket);
WSACleanup();
return 1;
}
while (1) {
int inSocket = accept(srvSocket, NULL, NULL);
if (inSocket == INVALID_SOCKET) {
fprintf(stderr, "accept socket failed with error %d\n", WSAGetLastError());
closesocket(srvSocket);
WSACleanup();
return 1;
}
struct clientData* cliData = cliArray;
int i = 0;
while ((i < MAX_CLIENTS) && cliArray[i].busy)
i++;
if (i >= MAX_CLIENTS) {
// To many clients, disconnect
closesocket(inSocket);
printf("Too many active clients (max=%d), discarding this one\n", MAX_CLIENTS);
continue;
}
cliData = &cliArray[i];
cliData->busy = 1;
cliData->inSocket = inSocket;
cliData->hThread = CreateThread(
NULL, // default security attributes
0, // use default stack size
ClientThreadFunction, // thread function name
cliData, // argument to thread function
0, // use default creation flags
&cliData->threadId); // returns the thread identifier
}
closesocket(srvSocket);
WSACleanup();
printf("Done.\n");
return 0;
}
最近开始接触C socket编程。经过几天的学习,我写了这个程序,它监听特定 IP 和端口上的连接:
#include <stdio.h>
#include <sys/types.h>
#include <sys/socket.h>
#include <netinet/in.h>
#include <stdlib.h>
#include <string.h>
#include <unistd.h>
#include <arpa/inet.h>
int main()
{
printf ("The program has started\n");
int sock, client_socket;
char buffer[1024];
char response[1024];
struct sockaddr_in server_address, client_address;
int i = 0;
int optval = 1;
socklen_t client_length;
sock = socket(AF_INET, SOCK_STREAM, 0);
if (setsockopt(sock, SOL_SOCKET, SO_REUSEADDR, &optval, sizeof(optval)) < 0)
{
printf("Error setting TCP socket options!\n");
return 1;
}
else {
printf ("TCP socket set successfully!\n");
}
server_address.sin_family = AF_INET;
server_address.sin_addr.s_addr = inet_addr("10.0.2.15");
server_address.sin_port = htons(5005);
int stat_check = bind (sock, (struct sockaddr*) &server_address, sizeof (server_address));
if (stat_check != 0)
{
printf ("Couldn't bind\n");
}
else {
printf ("binded successfully\n");
}
stat_check = listen(sock, 5);
if (!(stat_check == 0))
{
printf ("Failed to listen!\n");
}
else {
printf ("Listening...\n");
}
printf ("now the program will attempt to accept the connectionHSHA\n");
client_length = sizeof(client_address);
client_socket = accept (sock, (struct sockaddr*) &client_address, &client_length);
printf ("Socket Accepted or something happened\n");
if (client_socket == -1)
{
printf ("Couldn't accept connection!\n");
}
else
{
printf ("Connection Accepted!\n");
}
while (1)
{
jump:
bzero(&buffer, sizeof(buffer));
bzero(&response, sizeof(response));
printf("* Shell#%s~$: ", inet_ntoa(client_address.sin_addr));
fgets(buffer, sizeof(buffer), stdin);
strtok(buffer, "\n");
write(client_socket, buffer, sizeof(buffer));
if (strncmp("q", buffer, 1) == 0)
{
break;
}
else
{
recv(client_socket, response, sizeof(response), MSG_WAITALL);
printf("%s", response);
}
}
}
此程序在我的 Linux 系统中编译 100% 正常,但我需要它 运行 在 windows 上。当我使用 MinGW 编译器在我的 windows 上编译同一个程序时,它 运行 出现许多 missing-header 错误。不过windows里面有一些socket编程的库,比如winsock.h
。但是,当我将 winsock.h
替换为 <sys/socket>
并删除其他 Linux 库(arpa/inet.h
等)时,仍然会出现一些其他错误,例如 socklen_t undefined
。我也收到了一些警告。
总而言之,如果我想 运行 windows 上的这段代码,我不清楚我需要替换哪些等效的库、函数和数据类型。或者我可以用任何其他方式 运行 它在 windows 上吗?任何建议将不胜感激。
谢谢!
这是一个简单但完整的服务器示例,该示例使用 Windows 下的套接字为 TCP 提供服务。
它接受多个并发客户端并用一个线程为它们服务。 服务器接受来自每个客户端的命令行并在服务器端回显它们(通过简单的发送很容易回显给客户端)。如果命令是“退出”,则服务器关闭连接。
当然还有很多改进的空间。你有想法...
#include <stdio.h>
#include <stdlib.h>
#include <sys/types.h>
#include <WinSock2.h>
#define portNo 2100
#define MAX_CLIENTS 10
struct clientData {
int busy;
int inSocket;
HANDLE hThread;
DWORD threadId;
};
struct clientData cliArray[MAX_CLIENTS];
int cliCount;
DWORD WINAPI ClientThreadFunction(LPVOID lpParam)
{
struct clientData* cliData = (struct clientData*)lpParam;
printf("[%d] Client start. Socket=%d\n", cliData->inSocket, cliData->inSocket);
char buf[1024];
int rcvLen;
int rcvCount = 0;
char ch;
while (1) {
rcvLen = recv(cliData->inSocket, &ch, 1, 0);
if (rcvLen <= 0)
break;
if (ch == '\r')
continue; // Ignore return character (followed by '\n')
if (ch != '\n') {
putchar(ch);
buf[rcvCount++] = ch;
buf[rcvCount] = 0; // nul terminate string
}
else {
printf("\n[%d] Line=\"%s\"\n", cliData->inSocket, buf);
if (_stricmp(buf, "exit") == 0)
break;
rcvCount = 0;
buf[0] = 0;
}
}
closesocket(cliData->inSocket);
printf("[%d] Client terminated.\n", cliData->inSocket);
cliData->busy = 0;
return 1;
}
int main(int argc, char *argv[])
{
int iResult;
WSADATA wsaData;
// Initialize Winsock
iResult = WSAStartup(MAKEWORD(2, 2), &wsaData);
if (iResult != 0) {
printf("WSAStartup failed: %d\n", iResult);
return 1;
}
int srvSocket = socket(AF_INET, SOCK_STREAM, IPPROTO_TCP);
if (srvSocket < 0) {
fprintf(stderr, "Open socket failed with error %d\n", WSAGetLastError());
return 1;
}
struct sockaddr_in sockAddr;
memset(&sockAddr, 0, sizeof(sockAddr));
sockAddr.sin_family = AF_INET;
sockAddr.sin_port = htons(portNo);
sockAddr.sin_addr.s_addr = INADDR_ANY;
if (bind(srvSocket, (struct sockaddr*)&sockAddr, sizeof(sockAddr))) {
fprintf(stderr, "bind socket failed with error %d\n", WSAGetLastError());
closesocket(srvSocket);
WSACleanup();
return 1;
}
if (listen(srvSocket, 5)) {
fprintf(stderr, "listen socket failed with error %d\n", WSAGetLastError());
closesocket(srvSocket);
WSACleanup();
return 1;
}
while (1) {
int inSocket = accept(srvSocket, NULL, NULL);
if (inSocket == INVALID_SOCKET) {
fprintf(stderr, "accept socket failed with error %d\n", WSAGetLastError());
closesocket(srvSocket);
WSACleanup();
return 1;
}
struct clientData* cliData = cliArray;
int i = 0;
while ((i < MAX_CLIENTS) && cliArray[i].busy)
i++;
if (i >= MAX_CLIENTS) {
// To many clients, disconnect
closesocket(inSocket);
printf("Too many active clients (max=%d), discarding this one\n", MAX_CLIENTS);
continue;
}
cliData = &cliArray[i];
cliData->busy = 1;
cliData->inSocket = inSocket;
cliData->hThread = CreateThread(
NULL, // default security attributes
0, // use default stack size
ClientThreadFunction, // thread function name
cliData, // argument to thread function
0, // use default creation flags
&cliData->threadId); // returns the thread identifier
}
closesocket(srvSocket);
WSACleanup();
printf("Done.\n");
return 0;
}