udp service client
#python udp client
#!/usr/bin/python
# -*- coding: UTF-8 -*-
#
from socket import *
import os
import time
HOST = 'localhost'
PORT = 5015
BUFSIZE = 1024
ADDR = (HOST, 5014)
def main():
udpCliSock = socket(AF_INET, SOCK_DGRAM)
udpCliSock.bind(ADDR)
for i in xrange(0,10):
udpCliSock.sendto(str(i),('localhost',PORT))
print "success"
time.sleep(1)
pass
udpCliSock.close()
if __name__ == '__main__':
main()
说一下这几天折腾Udp通讯相关心得
#客户端在创建udp socket后,也需要先bind一个端口,不然发送到服务器的udp包,服务器解出来的端口号是不固定的。这应该是和协议的实现有关,和TCP不同,TCP客户端不需要bind。
#bind的端口和发送的端口号可以是不一样的。
void* runNet(void* data)
{
CCLOG("runNet,begin!");
sleep(1);
//设置可以由主线程取消子线程
if (pthread_setcancelstate(PTHREAD_CANCEL_ENABLE, NULL) != 0)
{
CCAssert(false, "UdpServer runNet set PTHREAD_CANCEL_ENABLE error");
}
if (pthread_setcancelstate(PTHREAD_CANCEL_ASYNCHRONOUS, NULL) != 0)
{
CCAssert(false, "UdpServer runNet set PTHREAD_CANCEL_ASYNCHRONOUS error");
}
UdpServer* _udpsever = (UdpServer*)data;
struct event_base *base;
struct event *signal_event;
struct event *data_event;
struct event *wakeup_event;
evutil_socket_t fd = -1;
int flag = 1;
int result = 0;
struct sockaddr_in sin;
#ifdef WIN32
WSADATA wsa_data;
WSAStartup(0x0201, &wsa_data);
#endif
base = event_base_new();
if (!base) {
CCLOG("runNet,Could not initialize libevent!\n");
return 0;
}
//set udp socket,bind port
fd = socket(AF_INET, SOCK_DGRAM, 0);
if ( fd < 0) {
evutil_closesocket(fd);
CCLOG("runNet can't create socket\n");
return 0;
}
if (evutil_make_socket_nonblocking(fd) < 0) {
evutil_closesocket(fd);
CCLOG("runNet can't set socket nonblocking\n");
return 0;
}
/* Set socket option */
result=setsockopt(fd, SOL_SOCKET, SO_REUSEADDR, (void*)&flag, sizeof(flag));
if (result < 0) {
evutil_closesocket(fd);
CCLOG("runNet setsockopt() error:%d\n",result);
return 0;
}
memset(&sin, 0, sizeof(sin));
sin.sin_family = AF_INET;
sin.sin_addr.s_addr = inet_addr(IPADDRESS);
sin.sin_port = htons(PORT);
if (bind(fd, (struct sockaddr *)&sin, sizeof(struct sockaddr)) < 0) {
evutil_closesocket(fd);
CCLOG("runNet bind() error\n");
return 0;
} else {
CCLOG("runNet bind() success - [%s] [%d]\n", IPADDRESS, PORT);
}
//set fd event
data_event=event_new(base, fd, EV_READ | EV_PERSIST, &read_cb, (void*)_udpsever);
if (!data_event || event_add(data_event, NULL)<0) {
evutil_closesocket(fd);
CCLOG("runNet Could not create/add a read Socket event!\n");
return 0;
}
_udpsever->socket = fd;
//set signal event,ctrl+c
signal_event = evsignal_new(base, SIGINT, signal_cb, (void *)base);
if (!signal_event || event_add(signal_event, NULL)<0) {
evutil_closesocket(fd);
CCLOG("runNet Could not create/add a signal event!\n");
return 0;
}
//wakeup
#ifdef WIN32
#define LOCAL_SOCKETPAIR_AF AF_INET
#else
#define LOCAL_SOCKETPAIR_AF AF_UNIX
#endif
evutil_socketpair(LOCAL_SOCKETPAIR_AF, SOCK_STREAM, 0, s_wakeupSocket);
wakeup_event = event_new(base, s_wakeupSocket[1], EV_READ | EV_PERSIST, wakeup_cb, (void*)_udpsever);
if (!wakeup_event || event_add(wakeup_event, NULL)<0)
{
evutil_closesocket(s_wakeupSocket[0]);
evutil_closesocket(s_wakeupSocket[1]);
CCLOG("runNet Could not create/add wakeup_event!\n");
return 0;
}
event_base_dispatch(base);
event_free(signal_event);
event_base_free(base);
CCLOG("UdpServer runNet function exit\n");
return 0;
}
static void read_cb(evutil_socket_t fd, short event, void *userData)
{
UdpServer* _udpServer = (UdpServer*)userData;
char buf[BUF_SIZE];
int size = sizeof(struct sockaddr);
struct sockaddr_in client_addr;
memset(buf, 0, sizeof(buf));
int len = recvfrom(_udpServer->socket,buf,BUF_SIZE,0,(struct sockaddr *)&client_addr,(socklen_t *)&size);
if (len == -1) {
CCLOG("udpSever recvfrom() error\n");
} else if (len == 0) {
CCLOG("udpSever Connection Closed\n");
} else {
MessageCenter* _msgC = _udpServer->getMessageCenter();
if(_msgC != NULL)
{
long ip = client_addr.sin_addr.s_addr;
// CCLOG("udpSever Read: len [%d] - content [%s] ipxxxxxxx:[%s]\n", len,buf,inet_ntoa(client_addr.sin_addr));
int port = ntohs(client_addr.sin_port);
CCLOG("udpSever Read: len [%d] - content [%s] ip:[%ld] port:[%d]\n", len, buf,ip,port);
MessageNode* _msgN = MessageNode::create(buf, len,ip,port);
_msgC->addMsgNode_RecvMsgQueue(_msgN);
}
/* Echo */
//sendto(fd, buf, len, 0, (struct sockaddr *)&client_addr, size);
}
}
static void signal_cb(evutil_socket_t sig, short events, void *user_data)
{
struct event_base *base = (struct event_base *)user_data;
struct timeval delay = {1,0};
printf("Caught an interrupt signal; exiting cleanly in two seconds.\n");
event_base_loopexit(base, &delay);
}
static void wakeup_cb(evutil_socket_t pairSocketId, short event, void *user_data)
{
UdpServer* _udpServer = (UdpServer*) user_data;
int size = sizeof(struct sockaddr);
evutil_socket_t fd = _udpServer->socket;
struct sockaddr_in sin;
MessageCenter* _msgC = _udpServer->getMessageCenter();
QueueMsgNode* _msgQ = _udpServer->msgQueue;
_msgC->get_SendMsgQueue(_msgQ);
QueueMsgNode::iterator it;
for (it=_msgQ->begin(); it!=_msgQ->end(); it++)
{
MessageNode* tmp = *it;
memset(&sin, 0, sizeof(sin));
sin.sin_family = AF_INET;
sin.sin_addr.s_addr = tmp->ip;
sin.sin_port = tmp->port;
CCLOG("wakeup_cb send---ip:%ld,port:%d,msg:%s \n",tmp->ip,tmp->port,tmp->msgPtr);
sendto(fd, tmp->msgPtr, tmp->msgLen, 0, (struct sockaddr *)&sin, size);
//谁用谁删除
delete tmp;
}
_msgQ->clear();
}
#贴一个用libevent写的server端。