我正在研究用C编写的服务器软件。我创建了一个用于设置名为config
的全局变量的函数,因此我可以在多个项目中使用此代码。
您可以从标题中获取错误消息。
typedef struct ntp_conn {
int domain; // addressfamily
int sType; // sockettype
int protocol; // protocol
int socket; // socketpointer
struct sockaddr_in *addr; // address
} ntp_conn;
和
int swf_config( int domain, int sType, int protocoll, char *ip, short int port ) {
config->domain = domain;
config->sType = sType;
config->protocol = protocoll;
config->addr->sin_family = AF_INET;
config->addr->sin_port = htons(port);
config->addr->sin_len = sizeof(struct sockaddr_in);
if( inet_pton(AF_INET, ip, &config->addr->sin_addr) < 0 )
printf("\nerror...");
return 0;
}
服务器功能包含套接字创建,绑定&amp;最后列出主循环。应将重新获取的信息重定向到处理程序文件,该文件计算特定结果。这个参数使功能模块化,对吗? ;)
swf_conn.c:
#define BUFFERSIZE 9084
#define MAXCONN 10
#include "swf_conn.h"
#include <sys/types.h>
#include <sys/socket.h>
#include <stdlib.h>
#include <string.h>
#include <errno.h>
#include <arpa/inet.h>
#include <netinet/in.h>
#include <stdio.h>
#include <unistd.h>
ntp_conn *config;
void swf_error( char* msg ) {
printf("\n** %s [%d]: %s", msg, errno, strerror(errno));
}
int swf_connect( ) {
config->socket = socket( config->domain, config->sType, config->protocol);
if( config->socket < 0 ) {
swf_error("SOCKET-ERROR:");
exit(-1);
}
if( connect((int)config->socket, (const struct sockaddr*)config->addr, sizeof(struct sockaddr_in)) < 0 ) {
swf_error("CONNECT-ERROR");
exit(-1);
}
return 0;
}
void swf_close( ) {
close( config->socket );
memset(&config, 0, sizeof(config));
}
int swf_config( int domain, int sType, int protocoll, char *ip, short int port ) {
// Good idea?
unsigned int addr;
if( strcmp(ip, "INADDR_ANY") == 0 )
addr = htonl(INADDR_ANY);
else
addr = inet_addr(ip);
config = (struct ntp_conn*) malloc(sizeof(struct ntp_conn));
config->addr = (struct sockaddr_in*) malloc(sizeof(struct sockaddr_in));
config->domain = domain;
config->sType = sType;
config->protocol = protocoll;
config->addr->sin_family = AF_INET;
config->addr->sin_port = htons(port);
config->addr->sin_len = sizeof(struct sockaddr_in);
config->addr->sin_addr.s_addr = htonl(INADDR_ANY);
memcpy( (char *)&config->addr->sin_addr, &addr, sizeof(addr));
return 0;
}
int swf_put( const void *data ) {
int recived = 0;
int sended = 0;
ntp_thread_recv *recvObj = malloc(sizeof(ntp_thread_recv));
ntp_thread_recv *sendObj = malloc(sizeof(ntp_thread_recv));
if( data == NULL ) {
swf_error("send-error: parameter == NULL");
exit(-1);
}
memcpy( &sendObj->data, &data, sizeof(data) );
printf("\n** sending");
sended = swf_send( sendObj );
if( sended > 0 )
printf("\n** sended %d bytes!\n**\n%s\n", (int)sended, (char*)sendObj->data);
recived = swf_recv( recvObj );
printf("\n** data recived! [%d]\n%s\n", (int)sizeof(recvObj), (char*) recvObj);
return 0;
}
int swf_send( ntp_thread_recv *sendData ) {
ssize_t sended = 0;
int sendSize = sizeof(sendData->data);
int i=0;
do {
sended = send( config->socket, &sendData->data[i], sendSize-sended, 0);
if( sended < 0) {
swf_error("send-error");
exit(-1);
}
} while( sended < sendSize );
return (int)sended;
}
int swf_recv( ntp_thread_recv *recvObj ) {
ssize_t recived = 0;
int recvLen = sizeof(char);
char buffer = (char) malloc(recvLen);
memset(&recvObj->data, 0, sizeof(recvLen*BUFFERSIZE));
int i = 0;
do {
recived = recv( config->socket, &buffer, recvLen, 0);
if( recived < 0) {
swf_error("recv-error");
exit(-1);
}
recvObj->data[(i++)] = buffer;
printf("%s\n", recvObj->data);
memset(&buffer, 0, sizeof(buffer));
} while ( recived > 0 && i < 20 );
printf("%s", recvObj->data);
return 0;
}
int swf_server( char *handleFile ) {
int client[MAXCONN];
struct sockaddr_in *clientAddr;
unsigned int len;
int i = 0;
for( i=0; i<MAXCONN; i++)
client[i] = 0;
i=0;
if( handleFile == NULL ) {
swf_error("handleFile empty!");
exit(-1);
}
config->socket = socket( config->domain, config->sType, config->protocol);
if( config->socket < 0 ) {
swf_error("SOCKET-ERROR:");
exit(-1);
}
if( bind( config->socket, (const struct sockaddr*)&config->addr, sizeof(config->addr) ) < 0 ) {
swf_error("can't bind on address");
exit(-1);
}
if( listen( config->socket, MAXCONN ) < 0 ) {
swf_error("can't listen on socket");
exit(-1);
}
printf("\n** server waiting for connections...");
for(;;) {
if( ( client[i] = accept( config->socket, (struct sockaddr*)&clientAddr, &len ) ) > 0 ) {
ntp_thread_recv *sendObj = malloc(sizeof(ntp_thread_recv));
ntp_thread_recv *recvObj = malloc(sizeof(ntp_thread_recv));
sendObj->data = "welcome to my server!\n\r";
if( swf_send(sendObj) < 0 ) {
swf_error("sending error");
continue;
}
memset(&sendObj, 0, sizeof(sendObj));
FILE *fp;
char *recvBuff[BUFFERSIZE];
char buff;
int j = 0;
while( client[i] > 0 ) {
if( swf_recv(recvObj) < 0 ) {
swf_error("reciving error");
continue;
}
if( strcmp( recvObj->data, "quit") == 0 ) {
client[i] = 0;
memset(&clientAddr, 0, sizeof(clientAddr));
printf("\n** client closed.");
continue;
}
strcat( recvBuff, handleFile );
strcat( recvBuff, recvObj->data );
if( ( fp = popen( recvBuff, "r" ) ) < 0 ) {
swf_error("can't execute the handle file!");
continue;
}
memset( &recvBuff, 0, sizeof(recvBuff) );
while( ( buff = fgetc(fp) ) )
memcpy(&recvBuff[i++], &buff, sizeof(buff));
if( j > 0 ) {
memcpy(&sendObj->data, &recvBuff, (j+1)*sizeof(char));
} else {
sendObj->data = "nothingtosend\n\r";
swf_error("can't read result from your handle file!");
}
j = 0;
memset(&recvBuff, 0, sizeof(recvBuff));
if( swf_send(sendObj) < 0 ) {
swf_error("sending error");
continue;
}
memset(&sendObj, 0, sizeof(sendObj));
}
} else {
client[i] = 0;
}
}
return 0;
}
main.c中:
#include <stdio.h>
#include <stdio.h>
#include "swf_conn.h"
#include <sys/socket.h>
#include <netinet/in.h>
int main(int argc, const char * argv[])
{
char *ip = "0.0.0.0";
// char *buff = ( char * ) malloc( 1024 * sizeof( char ) );
printf("\n SERVER\n");
printf("\n%s", ip);
if( swf_config( PF_INET, SOCK_STREAM, IPPROTO_TCP, ip, 81) < 0 )
printf("\n** ERROR: ");
else
printf("\n** socket created...");
if( swf_server("./handleFile") < 0 )
printf("\n** error!");
return 0;
}
输出:
SERVER
0.0.0.0
** socket created...
** can't bind on address [47]: Address family not supported by protocol family
关于这一点,应该是我的错,但我不明白。
谢谢你的帮助!
抱歉找不到代码!
答案 0 :(得分:0)
您似乎永远不会为config->addr
分配任何内存。我怀疑至少有一个问题。
拥有它会更容易:
typedef struct ntp_conn {
int domain; // addressfamily
int sType; // sockettype
int protocol; // protocol
int socket; // socketpointer
struct sockaddr_in addr; // address <- NOTE NO '*' HERE
} ntp_conn;
所以你不必担心吗?