我的建议,用C来做开发网络,kylix可以做外层,进程间通讯用IPC搞定,socket通讯在linux下用C来不是很难的事情,贴一个去年我写的linux下组播接收数据的代码片断,这些函数在windows下都有对应。
// copyright by simahuapeng
// 05-07-01
#include <stdio.h>
#include <stdlib.h>
#include <sys/types.h>
#include <sys/socket.h>
#include <sys/stat.h>
#include <time.h>
#include <string.h>
#include <netinet/in.h>
#include <errno.h>
#include <netdb.h>
#include <unistd.h>
#include <fcntl.h>
/*
* 功能 :
* 初始化传输进程的资源
* 此程序只用于服务端和客户端的传输进程
*
* 输入 :
* 无
*
* 返回 :
* 成功 : 0
* 失败 : -1
*/
static inline int open_multi ()
{
int rc = -1;
int i = 1;
/* 客户程序填充服务端的资料 */
memset(&transfers_addr,0,sizeof(transfers_addr));
transfers_addr.sin_family = AF_INET;
transfers_addr.sin_addr.s_addr = inet_addr(MULTI_ADDR);
transfers_addr.sin_port = SERVE_PORT;
/* 客户程序开始建立 transfers_sock描述符 */
if((transfers_sock = socket(AF_INET,SOCK_DGRAM,0))==-1)
{
fprintf(stderr,"socket Error:%s/a/n",strerror(errno));
gotodo
ne_err;
}
/* 设置端口复用 */
if (setsockopt(transfers_sock, SOL_SOCKET, SO_REUSEADDR, &i, sizeof(i)) < 0)
{
fprintf(stderr,"setsockopt SO_REUSEADDR error = %d./n", errno);
gotodo
ne_err;
}
/* bind到本地端口*/
if (bind(transfers_sock,(struct sockaddr *)&transfers_addr,sizeof(transfers_addr))==-1)
{
fprintf(stderr,"connect Error:%s/a/n",strerror(errno));
gotodo
ne_err;
}
#ifdef SET_TTL
i = TTL_VALUE;
if (setsockopt(transfers_sock, IPPROTO_IP, IP_MULTICAST_TTL, &i, sizeof(i)) < 0)
{
fprintf(stderr,"setsockopt IP_MULTICAST_TTL error = %d./n", errno);
gotodo
ne_err;
}
#endif
#ifdef SET_LOOP
/* 在同一个主机上进行广播设置套接口,作用是方便单个开发系统上测试多播IP广播 */
i = 1;
if (setsockopt(transfers_sock, IPPROTO_IP, IP_MULTICAST_LOOP, &i, sizeof(i)) < 0)
{
fprintf(stderr,"tsockopt IP_MULTICAST_LOOP error = %d./n", errno);
gotodo
ne_err;
}
#endif
/* 加入多播组 */
transfers_mreq.imr_multiaddr.s_addr = transfers_addr.sin_addr.s_addr;
transfers_mreq.imr_interface.s_addr = htonl(INADDR_ANY);
/* 防止DHCP没有初始化好 */
if (setsockopt(transfers_sock, IPPROTO_IP, IP_ADD_MEMBERSHIP, &transfers_mreq, sizeof(transfers_mreq)) < 0)
{
/* 添加组播路由表 */
}
/* 再来一次 */
if (setsockopt(transfers_sock, IPPROTO_IP, IP_ADD_MEMBERSHIP, &transfers_mreq, sizeof(transfers_mreq)) < 0)
{
if (errno)
{
fprintf(stderr,"setsockopt IP_ADD_MEMBERSHIP error = %d./n", errno);
gotodo
ne_err;
}
}
/* 创建回应包SOCKET */
if ((ack_sock = socket(AF_INET, SOCK_DGRAM, 0)) < 0)
{
fprintf(stderr,"open_multi : socket UDP error = %d, j = 0./n", errno);
gotodo
ne_err;
}
if (setsockopt(ack_sock, SOL_SOCKET, SO_REUSEADDR, &i, sizeof(i)) < 0)
{
fprintf(stderr,"open_multi : setsockopt SO_REUSEADDR error = %d./n", errno);
gotodo
ne_err;
}
rc = 0;
done_err:
/* 判断是否失败 */
if (rc==-1)
{
/* 结束通讯 */
if ( (transfers_sock>0) && (close(transfers_sock)<0) )
{
fprintf(stderr,"close transfers socket error = %d/n", errno);
}
if ( (ack_sock>0) && (close(ack_sock)<0) )
{
fprintf(stderr,"close ack socket error = %d/n", errno);
}
}
return rc;
}
/*
* 功能 :
* 通过udp回复服务器数据包
* 此程序只用于客户端的传输进程
*
* 输入 :
* buff : 存放接收数据的指针
* size : 存放接收数据的内存长度
*
* 返回 :
* 成功 : 0
* 失败 : -1
*/
static inline int udp_ack (char *buff, unsigned int size)
{
int rc=-1;
unsigned int namelen = sizeof (ack_addr);
/* 回复服务器已经收到完整的数据 */
while (size > 0)
{
int len;
if ((len = sendto(ack_sock,
buff,
size,
0,
(struct sockaddr *)&ack_addr,
namelen)) < 0)
{
/* EAGAIN : 写操作被阻塞,如果设置了 O_NONBLOCK 标志,则立刻返回,并报告此错误 */
if (errno != EAGAIN)
{
fprintf(stderr,"udp_ack : sendto error = %d./n", errno);
gotodo
ne_err;
}
else
{
continue;
}
}
else
if ((len != size) && (errno != EINTR))
{
fprintf(stderr,"udp_ack : udp_ack size is short. error = %d./n", errno);
gotodo
ne_err;
}
buff += len;
size -= len;
}
/* 数据包发送完毕 */
rc = 0;
done_err:
return rc;
}