linux socket编程的问题
linux socket编程,怎样才能实现一个基本的聊天程序,可以聊天 ,也可以发文件?希望达人指导~最好能贴出源码~
[解决办法]
这东东可大可小,你把要求说详细点。
[解决办法]
这是UDP传文件的一个sever端的程序:仅供参考:
如果改成Linux下,只需要改其中的一小部分就可以了。。。就是初始化那一些。。。
/******************************************************************
*FILENAME: sever.cpp
*DESCRIPTION: 本文件用来接收一个UDP传输来的文件 , 并且可以保证可靠
性传输.
*AUTHOR: roading
*DATE: 2007-4-12
*****************************************************************/
#include <stdio.h>
#include <winsock2.h>
#include <string.h>
#include <winbase.h>
#include <process.h>
#include <time.h>
#include <conio.h>
#define BUFLEN20460//除去五个标志位和一个结束符,其它的都可以用来传输数据
#define ADDR "192.168.6.106 "
#define SRVPORT8026//服务器端口号
#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( "文件传输开始,开始时间:%s\n ", ctime(&BeginTime));
//向服务器端发送数据
while (1)
{
//清空缓冲区
memset(RecvBuf, '\0 ',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] != '\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( "用时:%s\n ",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, '\0 ',SENDLEN);
int j = 0, temp = i;
while (temp/10)
{
j++;
temp = temp/10;
}
j++;
for (temp = 0; temp < 5-j; temp++)
{
SendBuf[temp] = '0 ';
}
sprintf(SendBuf + 5-j, "%d ",i);
}
/**************************************************************
FUNCTION:GetID
DESCRIPTION:根据接收缓冲区,获得序号
INPUT:SendBuf 缓冲区数据
OUTPUT:N/A
RETURN:序号
**************************************************************/
int GetID(char *SendBuf)
{
//判断SendBuf
if (SendBuf == NULL)
{
return PIONIT_NULL;
}
char temp[6] = {0};
int i = 0;
for(i = 0;i < 5 ;i++)
{
temp[i] = SendBuf[i];
}
return strtol(temp, NULL, 10);
}
[解决办法]
首先建立协议, 规范发送和传输的数据格式.
然后根据数据格式, 确定是聊天还是发文件.
最后进行相应处理.