好的,
首先如何运行我的程序:
#include <stdio.h> //printf
#include <string.h> //memset
#include <stdlib.h> //exit(0);
#include <arpa/inet.h>
#include <sys/socket.h>
#include <sys/types.h>
#include <time.h>
#include <netinet/tcp.h>
#include <getopt.h>
#include <string.h>
#include <fcntl.h>
#include <openssl/md5.h>
#include <limits.h>
#define BUFLEN 100 //Max length of buffer
void die(char *s)
{
perror(s);
exit(1);
}
struct Wiadomosc{
int nr_ksiegi;
int jednostka;
int czas;
int port;
};
char *str2md5(const char *str, int length) {
int n;
MD5_CTX c;
unsigned char digest[16];
char *out = (char*)malloc(33);
MD5_Init(&c);
while (length > 0) {
if (length > 512) {
MD5_Update(&c, str, 512);
} else {
MD5_Update(&c, str, length);
}
length -= 512;
str += 512;
}
MD5_Final(digest, &c);
for (n = 0; n < 16; ++n) {
snprintf(&(out[n*2]), 16*2, "%02x", (unsigned int)digest[n]);
}
return out;
}
void wyslij_udp(int port, const char* adres_server, struct Wiadomosc moja);
int polacz_tcp(int port, const char* server_adres);
int pobierz_argument(char *optarg)
{
char *endptr;
int val;
val = (int)strtol(optarg,&endptr,0);
if(endptr == optarg)
{
fprintf(stderr,"Niepoprawny paramtr funkcji \n");
exit(EXIT_FAILURE);
}
return val;
}
void print_usage() {
printf("Usage: \n./client -i numer_ip -o numer_portu -k numer_ksiegi -j jednostka \n-c czas -p port -d plik_wynikowy \n\nnumer_ip - numer ip servera\n-o - numer portu serwera\nnumer_ksiegi - numer ksiegi Pana Tadeusza <1,12> \njednostka - rodzaj wysylanych komunikatow: \na) 1 - wysylanie sa cale linie \nb) 2 - wysylanie sa slowa i nowe linie \nc) 3 - wysylanie sa znaki(litery,sredniki...) \nczas - czas pomiedzy poszczegolnymi komunikatami \nport - port otrzymywanych komunikatow \n");
}
int main(int argc, char *argv[])
{
int option = 0;
int ksiega = -1, jednostka = -1, czas = -1, port =-1,port2=-1;
int sockfd = 0, n = 0;
char *line;
size_t len = 0;
char recvBuff[LINE_MAX];
char* adres;
struct Wiadomosc moja;
int fd;
char* plik_wynikowy;
if(argc ==1)
{
print_usage();
exit(EXIT_FAILURE);
}
while ((option = getopt(argc, argv,"k:j:c:p:i:o:d:")) != -1) {
switch (option) {
case 'i' :
if(strlen(optarg) < 7 || strlen(optarg) > 21)
{
fprintf(stderr,"niepoprawny adres ip \n");
exit(EXIT_FAILURE);
}
adres = optarg;
break;
case 'o' :
port2 = pobierz_argument(optarg);
if( port2 < 0 || port2 > 65535 )
{
fprintf(stderr,"niepoprawna wartosc ksiegi! \n");
exit(EXIT_FAILURE);
}
break;
case 'k' :
ksiega = pobierz_argument(optarg);
if( ksiega < 0 || ksiega > 12 )
{
fprintf(stderr,"niepoprawna wartosc ksiegi! \n");
exit(EXIT_FAILURE);
}
break;
case 'j' :
jednostka = pobierz_argument(optarg);
if(jednostka < 1 || jednostka > 3)
{
fprintf(stderr,"niepoprawna wartosc jednostki! \n");
exit(EXIT_FAILURE);
}
break;
case 'c' :
czas = pobierz_argument(optarg);
if(czas < 0 || czas > 2000)
{
fprintf(stderr,"niepoprawna wartosc czasu! \n");
exit(EXIT_FAILURE);
}
break;
case 'p' :
port = pobierz_argument(optarg);
if(port < 0 || port > 65535)
{
fprintf(stderr,"niepoprawna wartosc portu! \n");
exit(EXIT_FAILURE);
}
break;
case 'd' :
if(strlen(optarg) < 2 )
{
fprintf(stderr,"niepoprawny plik wynikowy \n");
exit(EXIT_FAILURE);
}
plik_wynikowy = optarg;
break;
default: print_usage();
exit(EXIT_FAILURE);
}
}
moja.nr_ksiegi = ksiega;
moja.jednostka = jednostka;
moja.czas = czas;
moja.port = port;
wyslij_udp(port2,adres,moja);
// now WAITING FOR CONNECTION - ENJOY !
sleep(1);
fd = open(plik_wynikowy, O_WRONLY | O_CREAT | O_TRUNC);
memset(recvBuff,0,sizeof(recvBuff));
sockfd = polacz_tcp(5000, adres);
fprintf(stdout,"Trwa transmisja...\n");
while( ( recv(sockfd,recvBuff,sizeof(recvBuff),0) ) > 0 )
{
char *wiad;
//recvBuff[n] = 0;
write(fd,recvBuff,strlen(recvBuff));
/* if(fprintf(stdout,"%s",recvBuff) == EOF)
{
perror("fprintf");
}
fflush(stdout);
*/
// odebral - teraz wyslac
wiad = str2md5(recvBuff,strlen(recvBuff));
if( send(sockfd,wiad,33,0) == -1 )
{
fprintf(stderr, "Failure Sending Message\n");
}
free(wiad);
bzero( recvBuff, sizeof( recvBuff ) );
}
if(n<0)
{
printf("read error");
}
close(fd);
return 0;
}
void wyslij_udp(int port, const char* adres_server, struct Wiadomosc moja)
{
struct sockaddr_in si_other;
int s, i ;
int slen = sizeof(si_other);
if ( (s=socket(AF_INET, SOCK_DGRAM, IPPROTO_UDP)) == -1)
{
die("socket");
}
memset((char *) &si_other, 0, sizeof(si_other));
si_other.sin_family = AF_INET;
si_other.sin_port = htons(port);
if (inet_aton(adres_server , &si_other.sin_addr) == 0)
{
fprintf(stderr, "inet_aton() failed\n");
exit(1);
}
//send the message
if (sendto(s, (struct Wiadomosc*)&moja, 1024 + sizeof(moja) , 0 , (struct sockaddr *) &si_other,slen)==-1)
{
die("sendto()");
}
close(s);
}
int polacz_tcp(int port, const char* server_adres)
{
int sockfd = 0,r;
struct sockaddr_in serv_tcp;
if((sockfd = socket(AF_INET,SOCK_STREAM,0)) < 0)
{
die("socket");
}
memset(&serv_tcp,0,sizeof(serv_tcp));
serv_tcp.sin_family = AF_INET;
serv_tcp.sin_port = htons(port);
if(inet_pton(AF_INET,server_adres,&serv_tcp.sin_addr) < 0)
{
die("inet pton");
}
if(connect(sockfd,(struct sockaddr *)&serv_tcp, sizeof(serv_tcp))< 0)
{
die("conect");
}
return sockfd;
}
我的服务器
#include <stdio.h> //printf
#include <string.h> //memset
#include <stdlib.h> //exit(0);
#include <arpa/inet.h>
#include <sys/socket.h>
#include <time.h>
#include <netinet/tcp.h>
#include <getopt.h>
#include <dirent.h>
#include <openssl/md5.h>
#define SERVER "127.0.0.1"
struct Wiadomosc {
int nr_ksiegi;
int jednostka;
int czas;
int port;
};
void die(char *s);
char* getWord(FILE *fp);
void print_usage();
int pobierz_argument(char *optarg);
struct Wiadomosc* wczytaj_udp(int port);
int lacz_tcp(int port);
char* stradd(const char* a, const char* b);
char* str2md5(const char *str, int length);
int odbierz_i_policz_md5(int gniazdo,char *str1, int length)
{
char *out = (char*)malloc(33);
char *wiad;
if(recv(gniazdo, out, 33,0) != -1)
{
wiad = str2md5(str1,length) ;
if (strncmp (wiad,out,33) == 0)
{
free(out);
free(wiad);
return 1;
}
else
{
free(out);
free(wiad);
return 0;
}
}
else{
fprintf(stdout,"Recv error! \n");
exit(EXIT_FAILURE);
}
}
int main(int argc, char *argv[])
{
int option = 0;
int listenfd = 0;
int connfd = 0;
int sposob = 1;
int port=-1;
char* katalog;
int j=0;
char sendBuff[100];
time_t ticks;
FILE *stream;
char *ksiegi[12] = {"/1.txt","/2.txt","/3.txt","/4.txt","/5.txt","/6.txt","/7.txt","/8.txt","/9.txt","/10.txt","/11.txt","/12.txt"};
DIR* dir;
struct Wiadomosc * wiadomosc;
if(argc ==1)
{
print_usage();
exit(EXIT_FAILURE);
}
while ((option = getopt(argc, argv,"p:k:")) != -1) {
switch (option) {
case 'p' :
port = pobierz_argument(optarg);
if( port < 0 || port > 65535 )
{
fprintf(stderr,"niepoprawna wartosc ksiegi! \n");
exit(EXIT_FAILURE);
}
break;
case 'k' :
if( (strlen(optarg) < 3) || ((dir = opendir(optarg)) == NULL) )
{
fprintf(stderr,"niepoprawny katalog \n");
exit(EXIT_FAILURE);
}
katalog = optarg;
break;
default: print_usage();
exit(EXIT_FAILURE);
}
}
//ksiegi
for(j=0;j<12;j++)
{
ksiegi[j] = stradd(katalog,ksiegi[j]);
}
wiadomosc = wczytaj_udp(port);
printf("Nr ksiegi: %d \nJednostka: %d \nCzas: %d \nPort: %d \n" , wiadomosc->nr_ksiegi,wiadomosc->jednostka, wiadomosc->czas, wiadomosc->port);
sposob = wiadomosc->jednostka;
stream = fopen(ksiegi[(wiadomosc->nr_ksiegi)-1],"r");
if(stream == NULL)
die("open fail ");
memset(sendBuff,0,sizeof(sendBuff));
listenfd = lacz_tcp(wiadomosc->port);
listen(listenfd,10); //max number of connections
printf("waiting for connections..\n");
while(1)
{
ssize_t read;
size_t len = 0;
char* line = NULL;
char* word;
int j;
char znak[0];
int czas = wiadomosc->czas;
connfd = accept(listenfd,(struct sockaddr*) NULL,NULL);
if(sposob == 1)
{
while( (read = getline(&line,&len,stream) ) != -1)
{
write(connfd,line,read); // raad = zwraca wartosc ile
//czyta po linii, to jest ok
sleep(czas); // mala precyzja
if( !odbierz_i_policz_md5(connfd,line,read) )
{
perror("Blad MD5 \n");
}
}
}
else if(sposob == 2)
{
while(word = getWord(stream))
{
//printf("%s",word);
send(connfd,word,strlen(word),MSG_CONFIRM);
sleep(czas);
if( !odbierz_i_policz_md5(connfd,word,strlen(word)) )
{
perror("Blad MD5 \n");
}
}
}
else if(sposob == 3)
{
while( (word = fgets(znak,2,stream)) != NULL)
{
send(connfd,word,strlen(word),MSG_CONFIRM);
sleep(czas);
if( !odbierz_i_policz_md5(connfd,word,strlen(word)) )
{
perror("Blad MD5 \n");
}
}
}
close(connfd);
sleep(1);
free(line);
}
fclose(stream);
free(wiadomosc);
return 0;
}
char* stradd(const char* a, const char* b){
size_t len = strlen(a) + strlen(b);
char *ret = (char*)malloc(len * sizeof(char) + 1);
*ret = '\0';
return strcat(strcat(ret, a) ,b);
}
char *getWord(FILE *fp)
{
int n = 0;
char word[100];
int ch;
// get line and get word
while(ch = fgetc(fp))
{
if(ch == EOF)
return NULL;
else if(isalpha(ch))
word[n++] = ch;
else if(ch == '\n')
{
word[n++] = '\n';
break;
}
else if(isspace(ch))
{
word[n++] = ' ';
break;
}
else break;
}
word[n] = '\0';
return strdup(word);
}
void die(char *s)
{
perror(s);
exit(1);
}
void print_usage() {
printf("Usage: \n./server -p numm -k\n p- numer portu\nk-katalog\n");
}
int pobierz_argument(char *optarg)
{
char *endptr;
int val;
val = (int)strtol(optarg,&endptr,0);
if(endptr == optarg)
{
fprintf(stderr,"Niepoprawny paramtr funkcji \n");
exit(EXIT_FAILURE);
}
return val;
}
struct Wiadomosc* wczytaj_udp(int port)
{
struct sockaddr_in si_me, si_other;
struct Wiadomosc * temp = malloc(sizeof(struct Wiadomosc));
int s, i, slen = sizeof(si_other) , recv_len;
int r;
//create a UDP socket
if ((s=socket(AF_INET, SOCK_DGRAM, IPPROTO_UDP)) == -1)
{
die("socket");
}
// zero out the structure
memset((char *) &si_me, 0, sizeof(si_me));
si_me.sin_family = AF_INET;
si_me.sin_port = htons(port);
si_me.sin_addr.s_addr = htonl(INADDR_ANY);
//bind socket to port
if( bind(s , (struct sockaddr*)&si_me, sizeof(si_me) ) == -1)
{
die("bind");
}
//keep listening for data
printf("Waiting for data...");
fflush(stdout);
//try to receive some data, this is a blocking call
if ((recv_len = recvfrom(s, temp,sizeof(* temp), 0, (struct sockaddr *) &si_other, &slen)) == -1)
{
die("recvfrom()");
}
close(s);
return temp;
}
int lacz_tcp(int port)
{
int listenfd = 0;
struct sockaddr_in serv_tcp, saddr;
int r;
listenfd = socket(AF_INET,SOCK_STREAM,0); // now TCP
memset(&serv_tcp,0,sizeof(serv_tcp));
serv_tcp.sin_family = AF_INET;
serv_tcp.sin_addr.s_addr = htonl(INADDR_ANY);
serv_tcp.sin_port = htons(port);
if(bind(listenfd,(struct sockaddr*)&serv_tcp,sizeof(serv_tcp)) < 0)
{
die("bind()");
}
return listenfd;
}
char *str2md5(const char *str, int length) {
int n;
MD5_CTX c;
unsigned char digest[16];
char *out = (char*)malloc(33);
MD5_Init(&c);
while (length > 0) {
if (length > 512) {
MD5_Update(&c, str, 512);
} else {
MD5_Update(&c, str, length);
}
length -= 512;
str += 512;
}
MD5_Final(digest, &c);
for (n = 0; n < 16; ++n) {
snprintf(&(out[n*2]), 16*2, "%02x", (unsigned int)digest[n]);
}
return out;
}
如何编译?
服务器:gcc server.c -o server -lcrypto
客户端:gcc client.c -o client -lcrypto
你必须创建像mydir这样的dirr并放置文件1.txt。
如何运行?
./ server -p 12345 -k ksiegi /
./ client -i 127.0.0.1 -o 12345 -k 1 -j2 -c 1 -p 5432 -d XX
我的代码出了什么问题?
首先,我尝试连接UDP
并发送数据 - 效果很好。但在那之后 - 我想使用数据并创建TCP
连接和NOW:
有时它是工作,有时会失败。为什么?当我把端口像5000 - &gt;我正在尝试5432或5000 我的输出 :Connectron拒绝了。
有什么想法吗? 。
答案 0 :(得分:0)
listenfd = lacz_tcp(wiadomosc->port);
据我所知,在调用bind之前,端口尚未初始化。记录端口以确保服务器正在侦听正确的端口。