- 论坛徽章:
- 0
|
---------server.c------------
#include
#include
#include
#include
#include
#include
#include
#include
#include
#include
using namespace std;
#define M3UA_BUFSIZ 4096
#define MAX_ASSOC 16
enum Ctype{
SERVER,
CLIENT
};
static enum Ctype type;
static bool is_stopped = false;
static unsigned short localport;
static fd_set rfd;
static int maxfd = 0; //max associate fd + 1
static int lissock;
static vector accSock;
void printMSG(unsigned char buf[], int msglen)
{
printf("0000 | ");
for (int idx = 0; idx != msglen; ++idx)
printf("%02x ", buf[idx]);
printf("\n");
}
int HandleRecv(void)
{
int flags;
size_t fromlen;
struct sockaddr_in from;
struct sctp_sndrcvinfo sinfo;
static unsigned char buf[M3UA_BUFSIZ];
int msglen = 0;
for (vector::iterator it = accSock.begin(); it != accSock.end();)
{
if ((*it > 0) && (FD_ISSET(*it, &rfd)))
{
fromlen = sizeof(fromlen);
bzero(&from, sizeof(from));
bzero(&sinfo, sizeof(sinfo));
if ((msglen = sctp_recvmsg(*it, buf, sizeof(buf), (struct sockaddr* )(&from), &fromlen, &sinfo, &flags)) 0) && FD_ISSET(lissock, &rfd))
return HandleNewConnect();
return HandleRecv();
}
int max(const int mfd, const int fd)
{
return mfd > (fd + 1) ? mfd : (fd + 1);
}
void reset(void)
{
FD_ZERO(&rfd);
if ((lissock > 0) && FD_SET(lissock, &rfd))
maxfd = max(maxfd, lissock);
for (vector::const_iterator it = accSock.begin(); it != accSock.end(); ++it)
{
if ((*it > 0) && FD_SET(*it, &rfd))
maxfd = max(maxfd, *it);
}
}
int HandleRun(char err[])
{
struct timeval timeout;
while (!is_stopped)
{
timeout.tv_sec = 1;
timeout.tv_usec = 0;
reset();
switch (select(maxfd, &rfd, NULL, NULL, &timeout)){
case -1:
strcpy(err, "Process Select unsuccessfully");
goto execption;
case 0:
// time out
break;
default:
if (HandleSelect() == -1)
{
type == SERVER ? strcpy(err, "Cannot handle acceptable socket") : strcpy(err, "Remote Peer I/O shutdown OR Occur system failure");
goto execption;
}
}
}
return 0;
execption:
fprintf(stderr, "%s\n", err);
return -1;
}
bool initialize_server(char err[])
{
const int on = 1;
struct sockaddr_in svraddr;
struct sctp_initmsg initmsg;
struct sctp_event_subscribe events;
if (lissock > 0)
close(lissock);
if ((lissock = socket(AF_INET, SOCK_STREAM, IPPROTO_SCTP)) == -1)
{
strcpy(err, "Fail to create socket");
return false;
}
if (setsockopt(lissock, SOL_SOCKET, SO_REUSEADDR, &on, sizeof(on)) == -1)
{
strcpy(err, "Fail to setsockopt SO_REUSEADDR");
return false;
}
bzero(&svraddr, sizeof(svraddr));
svraddr.sin_family = AF_INET;
svraddr.sin_addr.s_addr = htonl(INADDR_ANY);
svraddr.sin_port = htons(localport);
if (bind(lissock, (struct sockaddr* )(&svraddr), sizeof(svraddr)) == -1)
{
strcpy(err, "Fail to bind locale address");
return false;
}
/* Specify that a maximum of 64 streams will be available per socket */
bzero(&initmsg, sizeof(initmsg));
initmsg.sinit_num_ostreams = 64;
initmsg.sinit_max_instreams = 64;
initmsg.sinit_max_attempts = 4;
if (setsockopt(lissock, IPPROTO_SCTP, SCTP_INITMSG, &initmsg, sizeof(initmsg)) == -1)
{
strcpy(err, "Fail to setsockopt SCTP_INITMSG");
return false;
}
/* Enable receipt of SCTP Snd/Rcv Data via sctp_recvmsg */
bzero(&events, sizeof(events));
events.sctp_association_event = 1;
events.sctp_data_io_event = 1;
if (setsockopt(lissock, SOL_SCTP, SCTP_EVENTS, (void* )(&events), sizeof(events)) == -1)
{
strcpy(err, "Fail to setsockopt SCTP_EVENTS");
return false;
}
/* Come into listening state */
if (listen(lissock, MAX_ASSOC) == -1)
{
strcpy(err, "Fail to get into listening");
return false;
}
maxfd = max(maxfd, lissock);
return true;
}
void setLocalport(const unsigned short lport)
{
localport = lport;
}
void setCType(const enum Ctype t)
{
type = t;
}
static void* routine(void* not_used)
{
pthread_detach(pthread_self());
void* ret = (void*)0x0;
char pmsg[] = {0x1, 0x2, 0x3, 0x4, 0x5, 0x6, 0x7, 0x8, 0x9, 0xa};
int msglen = sizeof(pmsg) / sizeof(*pmsg);
unsigned short streamId = 16;
while (!is_stopped)
{
for (vector::const_iterator it = accSock.begin(); it != accSock.end(); ++it)
{
if (sctp_sendmsg(*it, pmsg, msglen, NULL, 0, 0, 0, streamId, 0, 0) != msglen)
{
cerr
#include
#include
#include
#include
#include
#include
#include
#include
#include
using namespace std;
#define M3UA_BUFSIZ 4096
#define MAX_ASSOC 16
enum Ctype{
SERVER,
CLIENT
};
static enum Ctype type;
static bool is_stopped = false;
static char remoteip[20];
static unsigned short remoteport;
static int connsock = -1;
static fd_set rfd;
static int maxfd = 0; //max associate fd + 1
void printMSG(unsigned char buf[], int msglen)
{
printf("0000 | ");
for (int idx = 0; idx != msglen; ++idx)
printf("%02d ", buf[idx]);
printf("\n");
}
int HandleRecv(void)
{
int flags;
size_t fromlen;
struct sockaddr_in from;
struct sctp_sndrcvinfo sinfo;
static unsigned char buf[M3UA_BUFSIZ];
int msglen = 0;
if ((connsock > 0) && FD_ISSET(connsock, &rfd))
{
fromlen = sizeof(fromlen);
bzero(&from, sizeof(from));
bzero(&sinfo, sizeof(sinfo));
if ((msglen = sctp_recvmsg(connsock, buf, sizeof(buf), (struct sockaddr* )(&from), &fromlen, &sinfo, &flags)) (fd + 1) ? mfd : (fd + 1);
}
void reset(void)
{
FD_ZERO(&rfd);
if ((connsock > 0) && FD_SET(connsock, &rfd))
maxfd = max(maxfd, connsock);
}
int HandleRun(char err[])
{
struct timeval timeout;
while (!is_stopped)
{
timeout.tv_sec = 1;
timeout.tv_usec = 0;
reset();
switch (select(maxfd, &rfd, NULL, NULL, &timeout)){
case -1:
strcpy(err, "Process Select unsuccessfully");
goto execption;
case 0:
// time out
break;
default:
if (HandleSelect() == -1)
{
type == SERVER ? strcpy(err, "Cannot handle acceptable socket") : strcpy(err, "Remote Peer I/O shutdown OR Occur system failure");
goto execption;
}
}
}
return 0;
execption:
fprintf(stderr, "%s\n", err);
return -1;
}
bool initialize_client(char err[])
{
const int on = 1;
struct sockaddr_in svraddr;
struct sctp_initmsg initmsg;
struct sctp_event_subscribe events;
if (connsock > 0)
close(connsock);
if ((connsock = socket(AF_INET, SOCK_STREAM, IPPROTO_SCTP)) == -1)
{
strcpy(err, "Fail to create socket");
return false;
}
if (setsockopt(connsock, SOL_SOCKET, SO_REUSEADDR, &on, sizeof(on)) == -1)
{
strcpy(err, "Fail to setsockopt SO_REUSEADDR");
return false;
}
bzero(&svraddr, sizeof(svraddr));
svraddr.sin_family = AF_INET;
svraddr.sin_addr.s_addr = inet_addr(remoteip);
svraddr.sin_port = htons(remoteport);
/* Specify that a maximum of 64 streams will be available per socket */
bzero(&initmsg, sizeof(initmsg));
initmsg.sinit_num_ostreams = 64;
initmsg.sinit_max_instreams = 64;
initmsg.sinit_max_attempts = 4;
if (setsockopt(connsock, IPPROTO_SCTP, SCTP_INITMSG, &initmsg, sizeof(initmsg)) == -1)
{
strcpy(err, "Fail to setsockopt SCTP_INITMSG");
return false;
}
/* Enable receipt of SCTP Snd/Rcv Data via sctp_recvmsg */
bzero(&events, sizeof(events));
events.sctp_association_event = 1;
events.sctp_data_io_event = 1;
if (setsockopt(connsock, SOL_SCTP, SCTP_EVENTS, (void* )(&events), sizeof(events)) == -1)
{
strcpy(err, "Fail to setsockopt SCTP_EVENTS");
return false;
}
if (connect(connsock, (struct sockaddr* )(&svraddr), sizeof(svraddr)) == -1)
{
strcpy(err, "Fail to connect remote address");
return false;
}
maxfd = max(maxfd, connsock);
return true;
}
void setRemoteip(const char* rip)
{
strcpy(remoteip, rip);
}
void setRemoteport(const unsigned short rport)
{
remoteport = rport;
}
void setCType(const enum Ctype t)
{
type = t;
}
static void* routine(void* not_used)
{
pthread_detach(pthread_self());
void* ret = (void*)0x0;
char pmsg[] = {0xa, 0x9, 0x8, 0x7, 0x6, 0x5, 0x4, 0x3, 0x2, 0x1};
int msglen = sizeof(pmsg) / sizeof(*pmsg);
unsigned short streamId = 0x11;
while (!is_stopped)
{
if ((connsock > 0) && (sctp_sendmsg(connsock, pmsg, msglen, NULL, 0, 0, 0, streamId, 0, 0) != msglen))
{
cerr << "Cannot send message, Possibly remote peer shutdown" << endl;
ret = (void*)0x1;
break;
}
sleep(1);
}
pthread_detach(pthread_self());
return ret;
}
#ifndef NTEST
int main(int argc, char** argv)
{
char err[128];
setRemoteip("127.0.0.1");
setRemoteport(15000);
setCType(CLIENT);
pthread_t pid;
if (pthread_create(&pid, NULL, routine, NULL) != 0)
{
cerr << "Create pthread Unsuccessfully" << endl;
return -1;
}
if (initialize_client(err) != true)
{
fprintf(stderr, "Fail to initialize server: %s\n", err);
return -1;
}
if (HandleRun(err) == -1)
{
fprintf(stderr, "Fail to run recv/send: %s\n", err);
return -1;
}
cout << "Hello world" << endl;
return 0;
}
#endif //NTEST
本文来自ChinaUnix博客,如果查看原文请点:http://blog.chinaunix.net/u3/101003/showart_2139687.html |
|