我必须为我的一个讲座做一项作业,其中我必须用 C 语言在客户端和服务器程序之间创建连接。服务器程序和客户端程序必须在不同的 PC 上运行。启动 server.c 后:
之后我启动了 client.c:
我试图找出确切的问题。以下是我已经尝试过的一些事情:
这是我的代码: 服务器.c
#include <stdio.h>
#include <stdlib.h>
#include <unistd.h>
#include <arpa/inet.h>
#include <sys/socket.h>
#include <string.h>
// #include <libc.h>
#include "packet.h"
int main(int argc, char *argv[]){
if(argc != 4){ // Test ob 4 Programmargumente mitgegeben wurden
fprintf(stderr, "- Error: %s <IPv6 address> <port> <sNummer>\n", argv[0]);
exit(1);
}
struct packet received_packet, send_packet;
const char *ip = argv[1];
char* endptr;
long port_long = strtol(argv[2], &endptr, 10);
if(*endptr != '\0' || port_long < 0 || port_long > UINT16_MAX){
fprintf(stderr, "- invalid port number: %s\n", argv[2]);
exit(1);
}
uint16_t port =(uint16_t)port_long;
long sNummer_long = strtol(argv[3], &endptr, 10);
if(*endptr != '\0' || sNummer_long < 0 || sNummer_long > UINT32_MAX){
fprintf(stderr, "- invalid sNummer: %s\n", argv[3]);
exit(1);
}
send_packet.sNummer = (uint32_t)sNummer_long;
int csocket;
struct sockaddr_in6 addr;
socklen_t addrsize;
char test[1024];
csocket = socket(AF_INET6, SOCK_STREAM, 0);
if(csocket < 0 ){ // Test ob TCP-Socket erstellt wurde
perror("- socket error\n");
exit(1);
}
printf("+ TCP server socket created\n");
memset(&addr, 0, sizeof(addr));
addr.sin6_family = AF_INET6;
addr.sin6_port = htons(port);
inet_pton(AF_INET6, ip, &addr.sin6_addr);
if( connect(csocket, (struct sockaddr *) &addr, sizeof(addr)) < 0 ){
perror("- could not connect to server\n");
exit(1);
}
printf("+ Connected to server %s on port %d\n",ip, port);
printf("\n ----- message -----\n");
printf("text: ");
scanf("%s",send_packet.text);
printf("s%d > %s\n",send_packet.sNummer, send_packet.text);
send(csocket, &send_packet, sizeof(send_packet), 0);
ssize_t bytesRead = recv(csocket, &received_packet, sizeof(received_packet), 0);
if( bytesRead <= 0 ){
perror("- error receiving data from server\n");
}
test[bytesRead] = '\0';
printf("\n ----- Server -----\n");
printf("s%d > %s\n",received_packet.sNummer,received_packet.text);
close(csocket);
printf("\n+ disconnected from server\n");
return 0;
}
客户端.c
#include <stdio.h>
#include <stdlib.h>
#include <unistd.h>
#include <arpa/inet.h>
#include <sys/socket.h>
#include <string.h>
// #include <libc.h>
#include "packet.h"
#define BACKLOG 5
int main(int argc, char *argv[]){
if(argc != 3){ // Test ob auch 3 Programmargumente mitgegeben wurden
fprintf(stderr, "- Error: %s <port> <sNummer>\n",argv[0]);
exit(1);
}
struct packet received_packet, response_packet;
char* endptr;
long port_long = strtol(argv[1], &endptr, 10);
if(*endptr != '\0' || port_long < 0 || port_long > UINT16_MAX){
fprintf(stderr, "- invalid port number: %s\n", argv[1]);
exit(1);
}
uint16_t port =(uint16_t)port_long;
long sNummer_long = strtol(argv[2], &endptr, 10);
if(*endptr != '\0' || sNummer_long < 0 || sNummer_long > UINT32_MAX){
fprintf(stderr, "- invalid sNummer: %s\n", argv[2]);
exit(1);
}
response_packet.sNummer = (uint32_t)sNummer_long;
int server_socket, client_socket;
struct sockaddr_in6 s_addr, c_addr;
socklen_t c_addrsize;
char test[1024];
server_socket = socket(AF_INET6, SOCK_STREAM, 0);
if(server_socket < 0 ){
perror("- socket error\n");
exit(1);
}
printf("+ TCP server socket created\n");
memset(&s_addr, 0, sizeof(s_addr));
s_addr.sin6_family = AF_INET6;
s_addr.sin6_port = htons(port);
s_addr.sin6_addr = in6addr_any;
if(bind(server_socket, (struct sockaddr *) &s_addr, sizeof(s_addr)) < 0){
perror("- bind error\n");
exit(1);
}
printf("+ bind to port number: %d\n", port);
if(listen(server_socket, BACKLOG) < 0){
perror("- listening error, can't hear something\n");
exit(1);
}
printf("Listening...\n");
while(1){
c_addrsize = sizeof(c_addr);
client_socket = accept(server_socket, (struct sockaddr*)&c_addr, &c_addrsize);
if(client_socket > 0){
printf("+ Client connected\n");
}else {
printf("- No Client connected\n");
sleep(1);
continue;
}
ssize_t bytesRead = recv(client_socket, &received_packet, sizeof(received_packet), 0);
if( bytesRead <= 0 ){
perror("- error receiving data from client\n");
continue;
}
test[bytesRead] = '\0';
printf("\n ----- Client -----\n");
printf("s%d > %s\n",received_packet.sNummer, received_packet.text);
printf("\n ----- response -----\n");
printf("text: ");
scanf("%s",response_packet.text);
send(client_socket, &response_packet, sizeof(response_packet), 0);
close(client_socket);
printf("\n+ Client disconnected\n");
}
return 0;
}
最后是packet.h。这个数据包是我作业的一部分。它必须从客户端发送到服务器并返回。
#ifndef PACKET_H
#define PACKET_H
#include <stdint.h>
struct packet {
char text[1024];
uint32_t sNummer;
};
#endif
代码看起来没有什么问题。只需确保您使用的是正确的 ipv6 地址即可。 在服务器上运行
ip address
或 ifconfig
如果是 ip address
输出将是这样的
1: lo:
...
2: eth0:
link/ether ...
inet <IPv4> brd ... scope ...
...
inet6 <IPv6> scope ...
...
使用 ipv4 或 ipv6(两者都适用于您的代码)。 例如:我的 ipv4:
192.168.0.105/24
(ipv6 需要 /24
部分)
你的可能会类似
确保两台计算机连接到同一网络并且防火墙不会导致任何问题。尝试使用
sudo ufw disable
禁用防火墙。
没有。 IP 地址后面不需要写“%eth0”。