Fórum Ubuntu CZ/SK
Ubuntu pro osobní počítače => Software => Příkazový řádek a programování pro GNU/Linux => Téma založeno: ferri 20 Ledna 2013, 19:26:41
-
Dostal som zadanie naprogramovať v linuxe sieťové prepojenie dvoch počítačov.
Takže som pomocou návodov na internete naprogramoval program pre server tcp a klienta tcp.
Zdrojové súbory
server tcp
/*
* server_tcp.c v.1.0
*
* A simple tcp server
* ===================
*
*/
#include <stdio.h>
#include <stdlib.h>
#include <string.h>
#include <unistd.h>
#include <arpa/inet.h>
#include <sys/types.h>
#include <netinet/in.h>
#include <sys/socket.h>
#define MAXRCVLEN 500
int main(int argc, char *argv[])
{
struct sockaddr_in dest; /* socket info about the machine connecting to us */
struct sockaddr_in serv; /* socket info about our server */
int mast_socket; /* socket used to listen for incoming connection */
int con_socket; /* socket used for accepted connection */
char buffer[MAXRCVLEN + 1]; /* +1 so we can add null terminator */
int len; /* amount of sent or received data */
int port; /* port number */
socklen_t socksize = sizeof(struct sockaddr_in);
/* start program with port number */
if (argc != 2) {
fprintf(stderr, "Usage %s <port>\n", argv[0]);
return 1;
}
port = atoi(argv[1]);
/* create the master socket and check it worked */
if ((mast_socket = socket(AF_INET, SOCK_STREAM, 0)) == -1) {
perror("Creating master socket");
exit(EXIT_FAILURE);
}
/* zero the struct before filling the fields */
memset(&serv, 0, sizeof(serv));
serv.sin_family = AF_INET; /* set the type of connection to TCP/IP */
serv.sin_addr.s_addr = INADDR_ANY; /* set our address to any interface */
serv.sin_port = htons(port); /* set the server port number */
/* bind serv information to master socket */
if (bind(mast_socket, (struct sockaddr *)&serv, socksize) == -1) {
perror("bind()");
return 1;
}
/* start listening, allowing a queue of up to 1 pending connection */
if (listen(mast_socket, 1) == -1) {
perror("listen()");
return 1;
}
/* accept one connection */
if ((con_socket = accept(mast_socket, (struct sockaddr *)&dest,
&socksize)) == -1) {
perror("accept()");
return 1;
}
/* address of incomming connection */
printf("Incoming connection from %s\n", inet_ntoa(dest.sin_addr));
/* message "quit" ends receiving/sending data */
while (strcmp(buffer, "quit\n") != 0) { /* received end */
/* inserting data for sending */
printf("Enter data for client: ");
if (fgets(buffer, MAXRCVLEN, stdin) == NULL) {
fprintf(stderr, "fgets()\n");
return 1;
}
/* sending data */
if ((len = send(con_socket, buffer, strlen(buffer), 0)) == -1) {
perror("send()");
return 1;
}
printf("Sent: %d bytes\n", len);
/* it was sent message about end of connection */
if (strcmp(buffer, "quit\n") == 0)
break; /* finish at once */
/* receiving data */
if ((len = recv(con_socket, buffer, MAXRCVLEN, 0)) == -1) {
perror("recv()");
return 1;
}
/* have to null terminate the received data ourselves */
buffer[len] = '\0';
printf("From client: %s", buffer);
printf("Received: %d bytes\n", len);
}
/* shutdown sockets properly */
close(con_socket);
close(mast_socket);
return 0;
}
klient tcp
/*
* client_tcp.c v.1.0
*
* A simple tcp client
* ===================
*
*/
#include <stdio.h>
#include <stdlib.h>
#include <string.h>
#include <unistd.h>
#include <netdb.h>
#include <arpa/inet.h>
#include <sys/types.h>
#include <netinet/in.h>
#include <sys/socket.h>
#define MAXRCVLEN 500
int main(int argc, char *argv[])
{
char buffer[MAXRCVLEN + 1]; /* +1 so we can add null terminator */
char *remote_host; /* server name or IP */
int my_socket; /* socket used for connection */
int len; /* amount of sent or received data */
int remote_port; /* server port number */
struct hostent *host_ptr; /* remote host */
struct sockaddr_in dest; /* socket info about server to connect */
socklen_t socksize = sizeof(struct sockaddr_in);
/* start program with sever name/IP and port number */
if (argc != 3) {
fprintf(stderr, "Usage %s <server_host> <server_port>\n", argv[0]);
return 1;
}
remote_host = argv[1];
remote_port = atoi(argv[2]);
/* resolve information about remote server */
if ((host_ptr = gethostbyname(remote_host)) == NULL) { /* from name */
if ((host_ptr = gethostbyaddr(remote_host, strlen(remote_host),
AF_INET)) == NULL) { /* or from IP number */
perror("Error resolving server address");
return 1;
}
}
/* create socket and check it worked */
if ((my_socket = socket(AF_INET, SOCK_STREAM, 0)) == -1) {
perror("Creating socket");
return 1;
}
/* zero the struct before filling the fields */
memset(&dest, 0, sizeof(dest));
dest.sin_family = AF_INET; /* set the type of connection to TCP/IP */
dest.sin_port = htons(remote_port); /* set destination port number */
/* set destination IP address */
memcpy(&(dest.sin_addr.s_addr), host_ptr->h_addr, host_ptr->h_length);
/* connect socket */
if (connect(my_socket, (struct sockaddr *)&dest, socksize) == -1) {
perror("connect()");
return 1;
}
/* message "quit" ends receiving/sending data */
while (strcmp(buffer, "quit\n") != 0) { /* sent end */
/* receiving data */
if ((len = recv(my_socket, buffer, MAXRCVLEN, 0)) == -1) {
perror("recv()");
return 1;
}
/* have to null terminate the received data ourselves */
buffer[len] = '\0';
printf("From server: %s", buffer);
printf("Received: %d bytes\n", len);
/* it was received message about end of connection */
if (strcmp(buffer, "quit\n") == 0)
break; /* finish at once */
/* inserting data for sending */
printf("Enter data for server: ");
if (fgets(buffer, MAXRCVLEN, stdin) == NULL) {
fprintf(stderr, "fgets()\n");
return 1;
}
/* sending data */
if ((len = send(my_socket, buffer, strlen(buffer), 0)) == -1) {
perror("send()");
return 1;
}
printf("Sent: %d bytes\n", len);
}
/* shutdown socket properly */
close(my_socket);
return 0;
}
Na testovanie vytvorených programov sieťového prepojenia používam počítač s nainštalovanou Fedora 17. Druhý zapožičaný počítač beží z live cd Kubuntu 9.10 kvôli jeho veku. Počítače sú prepojené sieťovým káblom. Mám aj krížený, ale netreba. Spojenie funguje aj na obyčajnom.
Na Fedora 17 nastavujem sieťovú kartu cez
ifconfig eth0 192.168.1.1 netmask 255.255.255.0 up
Na Kubuntu
ifconfig eth0 192.168.1.2 netmask 255.255.255.0 up
Paradox je, že spojenie funguje iba v prípade, že na Kubuntu spustím serverovú aplikáciu a na Fedore spustím klientovu aplikáciu. Opačne to nefunguje.
Skúsil som aj navzájom vymeniť IP adresy, ale nepomohlo. Stále musím na Kubuntu spustiť serverový program a na Fedore klientov program.
Vedel by mi niekto poradiť, prečo to tak je?
-
Zkusil bych ten křížený, když jej máš doma a pak špekuloval.
-
Nakoniec ma napadlo nahodiť na oba počítače rovnaké live systémy, keďže sa mi nechcelo vŕtať v zabezpečení dobre fungujúcej Fedora 17.
Nahodil som na oba počítače Kubuntu 9.10 live, prepojil káblom, nastavil IPčky, nahral cez USB skompivané programy server_tcp a client_tcp. Spustil som tak aj naopak a všetko fungovalo bez problémov.
Takže problém bol v silnom zabezpečení Fedora 17.
Programy sú v poriadku. :)