当前位置: 技术问答>linux和unix
linux socket编程的问题
来源: 互联网 发布时间:2016-02-24
本文导语: linux socket编程,怎样才能实现一个基本的聊天程序,可以聊天 ,也可以发文件?希望达人指导~最好能贴出源码~ | 这是UDP传文件的一个sever端的程序:仅供参考: 如果改成Linux下,只需要...
linux socket编程,怎样才能实现一个基本的聊天程序,可以聊天 ,也可以发文件?希望达人指导~最好能贴出源码~
|
这是UDP传文件的一个sever端的程序:仅供参考:
如果改成Linux下,只需要改其中的一小部分就可以了。。。就是初始化那一些。。。
/******************************************************************
*FILENAME: sever.cpp
*DESCRIPTION: 本文件用来接收一个UDP传输来的文件 , 并且可以保证可靠
性传输.
*AUTHOR: roading
*DATE: 2007-4-12
*****************************************************************/
#include
#include
#include
#include
#include
#include
#include
#define BUFLEN 20460 //除去五个标志位和一个结束符,其它的都可以用来传输数据
#define ADDR "192.168.6.106"
#define SRVPORT 8026 //服务器端口号
#define CILPORT 8025 //客户端端口号
#define FILE_SEND_END 633
#define SENDLEN 6 //发送数据长度
#define PIONIT_NULL 100 //错误号,指针为空
#define SENDNUM 500 //最多重发的次数
time_t BeginTime, EndTime, UsrTime;
int GetID(char *); //获得报文的ID号
void SetID(char *,int); //设定报文的ID号
int main()
{
int Timer2 = SENDNUM;
WSAData wsadata;
FILE *frecv;
sockaddr_in clientaddr, srvaddr;
SOCKET s;
int nRc, clientlen = sizeof(clientaddr), Serial = 0 ,ACKnum = 0;
char RecvBuf[BUFLEN] = {0} ,SendBuf[SENDLEN];
//初始化winsocket
nRc = WSAStartup(MAKEWORD(2, 2), &wsadata);
if(nRc)
{
printf("error in init the winsock n");
return ERROR_NO_NETWORK;
}
printf("winsock initialized!n");
//创建udp socket
s = socket(AF_INET, SOCK_DGRAM, 0);
if (s == INVALID_SOCKET)
{
printf("socket create error!n");
WSACleanup();
return ERROR_NO_NETWORK;
}
printf("socket created sucess!n");
//绑定一个本地端口
srvaddr.sin_family = AF_INET;
srvaddr.sin_port = htons(SRVPORT);
srvaddr.sin_addr.S_un.S_addr = htonl(INADDR_ANY);
nRc = bind(s, (LPSOCKADDR)&srvaddr, sizeof(srvaddr));
if (nRc == SOCKET_ERROR)
{
printf("port bind error !n");
closesocket(s);
WSACleanup();
return ERROR_NO_NETWORK;
}
printf("port bind ok !n");
clientaddr.sin_family = AF_INET;
clientaddr.sin_port = htons(CILPORT);
clientaddr.sin_addr.S_un.S_addr = inet_addr(ADDR);
frecv = fopen("recv", "wb");
if (frecv == NULL)
{
printf(" file open error !n");
}
unsigned long K = 1;
SetID(SendBuf, ACKnum);
time(&BeginTime);
printf("请确认客户端是开放的, 按任意键开始传输n");
getch();
printf("文件传输开始,开始时间:%sn", ctime(&BeginTime));
//向服务器端发送数据
while (1)
{
//清空缓冲区
memset(RecvBuf,'',BUFLEN);
//设置非阻塞模式
ioctlsocket(s,FIONBIO,&K);
nRc = recvfrom(s, RecvBuf, BUFLEN, 0, (SOCKADDR *)&clientaddr, &clientlen);
//判断是否已经重传到最大次数
if (Timer2 == 0)
{
printf("文件传输失败,网络断开或者对方终止传输 n");
return ERROR_NETWORK_UNREACHABLE;
}
//判断是否接收成功
if (RecvBuf[0] != '')
{
Timer2 = SENDNUM;
Serial = GetID(RecvBuf);
//如果接收的不是ACKnum,重发
if (Serial != ACKnum)
{
SetID(SendBuf, ACKnum);
sendto(s, SendBuf, sizeof(SendBuf), 0, (SOCKADDR *)&clientaddr, sizeof(clientaddr) );
}
else
{
//判断是否到文件尾
if (strlen(RecvBuf) == 5)
{
time(&EndTime);
printf("文件传输成功 !n");
printf("用时:%sn",ctime(&EndTime));
//结束,发送两次结束信号
SetID(SendBuf,99999);
sendto(s, SendBuf, sizeof(SendBuf), 0, (SOCKADDR *)&clientaddr, sizeof(clientaddr) );
sendto(s, SendBuf, sizeof(SendBuf), 0, (SOCKADDR *)&clientaddr, sizeof(clientaddr) );
closesocket(s);
WSACleanup();
fclose(frecv);
return FILE_SEND_END;
}
else
{
//写入到文件,并且ACK加1,发送
fwrite(RecvBuf + 5, sizeof(char), strlen(RecvBuf) - 6, frecv);
ACKnum++;
SetID(SendBuf, ACKnum);
sendto(s, SendBuf, sizeof(SendBuf), 0, (SOCKADDR *)&clientaddr, sizeof(clientaddr) );
}
}
}
//没有数据到,重发,并且启动计数器
else
{
Timer2--;
sendto(s, SendBuf, sizeof(SendBuf), 0, (SOCKADDR *)&clientaddr, sizeof(clientaddr) );
Sleep(20);
}
}
}
/**************************************************************
FUNCTION: setID
DESCRIPTION: 根据序列号,设定ACK的序号
INPUT: int i ,序列号
OUTPUT: 设定后存入 SendBuf
RETURN: void
**************************************************************/
void SetID(char *SendBuf,int i)
{
memset(SendBuf,'',SENDLEN);
int j = 0, temp = i;
while (temp/10)
{
j++;
temp = temp/10;
}
j++;
for (temp = 0; temp
如果改成Linux下,只需要改其中的一小部分就可以了。。。就是初始化那一些。。。
/******************************************************************
*FILENAME: sever.cpp
*DESCRIPTION: 本文件用来接收一个UDP传输来的文件 , 并且可以保证可靠
性传输.
*AUTHOR: roading
*DATE: 2007-4-12
*****************************************************************/
#include
#include
#include
#include
#include
#include
#include
#define BUFLEN 20460 //除去五个标志位和一个结束符,其它的都可以用来传输数据
#define ADDR "192.168.6.106"
#define SRVPORT 8026 //服务器端口号
#define CILPORT 8025 //客户端端口号
#define FILE_SEND_END 633
#define SENDLEN 6 //发送数据长度
#define PIONIT_NULL 100 //错误号,指针为空
#define SENDNUM 500 //最多重发的次数
time_t BeginTime, EndTime, UsrTime;
int GetID(char *); //获得报文的ID号
void SetID(char *,int); //设定报文的ID号
int main()
{
int Timer2 = SENDNUM;
WSAData wsadata;
FILE *frecv;
sockaddr_in clientaddr, srvaddr;
SOCKET s;
int nRc, clientlen = sizeof(clientaddr), Serial = 0 ,ACKnum = 0;
char RecvBuf[BUFLEN] = {0} ,SendBuf[SENDLEN];
//初始化winsocket
nRc = WSAStartup(MAKEWORD(2, 2), &wsadata);
if(nRc)
{
printf("error in init the winsock n");
return ERROR_NO_NETWORK;
}
printf("winsock initialized!n");
//创建udp socket
s = socket(AF_INET, SOCK_DGRAM, 0);
if (s == INVALID_SOCKET)
{
printf("socket create error!n");
WSACleanup();
return ERROR_NO_NETWORK;
}
printf("socket created sucess!n");
//绑定一个本地端口
srvaddr.sin_family = AF_INET;
srvaddr.sin_port = htons(SRVPORT);
srvaddr.sin_addr.S_un.S_addr = htonl(INADDR_ANY);
nRc = bind(s, (LPSOCKADDR)&srvaddr, sizeof(srvaddr));
if (nRc == SOCKET_ERROR)
{
printf("port bind error !n");
closesocket(s);
WSACleanup();
return ERROR_NO_NETWORK;
}
printf("port bind ok !n");
clientaddr.sin_family = AF_INET;
clientaddr.sin_port = htons(CILPORT);
clientaddr.sin_addr.S_un.S_addr = inet_addr(ADDR);
frecv = fopen("recv", "wb");
if (frecv == NULL)
{
printf(" file open error !n");
}
unsigned long K = 1;
SetID(SendBuf, ACKnum);
time(&BeginTime);
printf("请确认客户端是开放的, 按任意键开始传输n");
getch();
printf("文件传输开始,开始时间:%sn", ctime(&BeginTime));
//向服务器端发送数据
while (1)
{
//清空缓冲区
memset(RecvBuf,'',BUFLEN);
//设置非阻塞模式
ioctlsocket(s,FIONBIO,&K);
nRc = recvfrom(s, RecvBuf, BUFLEN, 0, (SOCKADDR *)&clientaddr, &clientlen);
//判断是否已经重传到最大次数
if (Timer2 == 0)
{
printf("文件传输失败,网络断开或者对方终止传输 n");
return ERROR_NETWORK_UNREACHABLE;
}
//判断是否接收成功
if (RecvBuf[0] != '')
{
Timer2 = SENDNUM;
Serial = GetID(RecvBuf);
//如果接收的不是ACKnum,重发
if (Serial != ACKnum)
{
SetID(SendBuf, ACKnum);
sendto(s, SendBuf, sizeof(SendBuf), 0, (SOCKADDR *)&clientaddr, sizeof(clientaddr) );
}
else
{
//判断是否到文件尾
if (strlen(RecvBuf) == 5)
{
time(&EndTime);
printf("文件传输成功 !n");
printf("用时:%sn",ctime(&EndTime));
//结束,发送两次结束信号
SetID(SendBuf,99999);
sendto(s, SendBuf, sizeof(SendBuf), 0, (SOCKADDR *)&clientaddr, sizeof(clientaddr) );
sendto(s, SendBuf, sizeof(SendBuf), 0, (SOCKADDR *)&clientaddr, sizeof(clientaddr) );
closesocket(s);
WSACleanup();
fclose(frecv);
return FILE_SEND_END;
}
else
{
//写入到文件,并且ACK加1,发送
fwrite(RecvBuf + 5, sizeof(char), strlen(RecvBuf) - 6, frecv);
ACKnum++;
SetID(SendBuf, ACKnum);
sendto(s, SendBuf, sizeof(SendBuf), 0, (SOCKADDR *)&clientaddr, sizeof(clientaddr) );
}
}
}
//没有数据到,重发,并且启动计数器
else
{
Timer2--;
sendto(s, SendBuf, sizeof(SendBuf), 0, (SOCKADDR *)&clientaddr, sizeof(clientaddr) );
Sleep(20);
}
}
}
/**************************************************************
FUNCTION: setID
DESCRIPTION: 根据序列号,设定ACK的序号
INPUT: int i ,序列号
OUTPUT: 设定后存入 SendBuf
RETURN: void
**************************************************************/
void SetID(char *SendBuf,int i)
{
memset(SendBuf,'',SENDLEN);
int j = 0, temp = i;
while (temp/10)
{
j++;
temp = temp/10;
}
j++;
for (temp = 0; temp