我使用以下命令编译了客户端和服务器代码:
服务器:
gcc server.c -o server.exe -lws2_32
gcc client.c -o client.exe -lws2_32
两个代码均已成功编译并生成 .exe 文件 w.r.t
server.c
和 client.c
文件。
我的问题是,当我运行
server.exe
文件时,它会自动打开并突然关闭。
这也发生在
client.exe
上。
这是为什么?
服务器.c:
#include <stdio.h>
#include <stdlib.h>
#include <string.h>
#include <winsock2.h>
#define SIZE 1024
void write_file(int sockfd){
int n;
FILE *fp;
char *filename = "file2.txt";
char buffer[SIZE];
fp = fopen(filename, "w");
if(fp==NULL){
perror("[-]Error in creating file.");
exit(1);
}while(1){
n = recv(sockfd, buffer, SIZE, 0);
if(n<=0){
break;
return;
}
fprintf(fp, "%s", buffer);
memset(buffer, 0, SIZE);
}
return;
}
int main (){
char *ip = "127.0.0.1";
int port = 8080;
int e;
int sockfd, new_sock;
struct sockaddr_in server_addr, new_addr;
int addr_size;
char buffer[SIZE];
sockfd = socket(AF_INET, SOCK_STREAM, 0);
if(sockfd<0){
perror("[-]Error in socket");
exit(1);
}
printf("[+]Server socket created. \n");
server_addr.sin_family = AF_INET;
server_addr.sin_port = port;
server_addr.sin_addr.s_addr = inet_addr(ip);
e = bind(sockfd,(struct sockaddr*)&server_addr, sizeof(server_addr));
if(e<0){
perror("[-]Error in Binding");
exit(1);
}
printf("[+]Binding Successful.\n");
e = listen(sockfd, 10);
if(e==0){
printf("[+]Listening...\n");
}
else{
perror("[-]Error in Binding");
exit(1);
}
addr_size = sizeof(new_addr);
new_sock = accept(sockfd,(struct sockaddr*)&new_addr, &addr_size);
write_file(new_sock);
printf("[+]Data written in the text file ");
return 0;
}
客户端.c:
#include <stdio.h>
#include <stdlib.h>
#include <unistd.h>
#include <string.h>
#include <winsock2.h>
#define SIZE 1024
void send_file(FILE *fp, int sockfd){
char data[SIZE] = {0};
while(fgets(data, SIZE, fp)!=NULL){
if(send(sockfd, data, sizeof(data), 0)== -1){
perror("[-] Error in sending data");
exit(1);
}
memset(data, 0, SIZE);
}
}
int main(){
char *ip = "127.0.0.1";
int port = 8080;
int e;
int sockfd;
struct sockaddr_in server_addr;
FILE *fp;
char *filename = "file.txt";
sockfd = socket(AF_INET, SOCK_STREAM, 0);
if(sockfd<0){
perror("[-]Error in socket");
exit(1);
}
printf("[+]Server socket created. \n");
server_addr.sin_family = AF_INET;
server_addr.sin_port = port;
server_addr.sin_addr.s_addr = inet_addr(ip);
e = connect(sockfd, (struct sockaddr*)&server_addr, sizeof(server_addr));
if(e == -1){
perror("[-]Error in Connecting");
exit(1);
}
printf("[+]Connected to server.\n");
fp = fopen(filename, "r");
if(fp == NULL){
perror("[-]Error in reading file.");
exit(1);
}
send_file(fp,sockfd);
printf("[+] File data send successfully. \n");
close(sockfd);
printf("[+]Disconnected from the server. \n");
return 0;
}
输出文件:
这是终端:
我在 Windows 机器上尝试此代码。
请帮我解决这个问题。
从我在你的问题中看到的,你说你是通过单击
.exe
文件来打开它的,对吗?
这里的问题似乎你无法看到任何步骤是否失败,因为当你在 Windows 中单击非 GUI 程序时,它会在临时终端上打开,并在程序结束时关闭。因此,如果程序在途中遇到任何错误并且套接字无法侦听,则程序不会阻塞,并且会结束而不留下任何痕迹。
要克服这个问题,您可以尝试两种替代方法:
我不是 Windows 专家,也没有 Windows 机器来测试此替代方案,但您应该能够输入类似以下内容:
PS C:\Users\ASUS\Desktop\Socket Program> server.exe
stdin
函数末尾添加 main()
读取在
return 0;
行和每个 exit()
行之前,添加以下行:
scanf("%d\n", &port);
选择
port
变量是为了方便编辑,看起来丑陋,但很实用。
客户端和服务器都会立即失败,因为您在调用
socket()
函数之前没有初始化 Winsock 库。在 Windows 上,您必须首先调用 WSAStartup()
!否则,socket()
将失败并显示 WSANOTINITIALISED
(10093) 错误代码:
尚未执行成功的 WSAStartup。
应用程序尚未调用 WSAStartup 或 WSAStartup 失败。
此要求仅存在于 Windows 上,其他平台没有其套接字库的初始化函数。而且这段代码绝对不是针对 Windows 编写的 - 明显的是缺少
WSAStartup()
、使用 int
而不是 SOCKET
作为套接字描述符、使用 <unistd.h>
等。这些做法在其他平台上很常见,例如“Nix 系统”。