网络协议栈0:从一个例子开始
最近因工作需要写一个网卡驱动,晕倒,没有任何网络知识,就写网络驱动!
可是,为了五斗米糊口,不得不从啊
于是,打算从网络协议栈开始,把网络搞一搞。
我们常常知道socket的用法(其实我还没有真正的写过socket代码,常常都是指那些socket高手了^-^),因此,打算从一个常用的实例开始,把网络协议栈整理一下,即把自己的学习经过进行记录,看看菜鸟的轨迹,是如何拐弯,颠簸。
通常的socket编程分两部分吧(错了别怪我,我不是高手),一是client部分,二是server部分,而更通常的情况是我们都以写client的任务为多,因此,从简单下手,当然选择client端开始了。
下面的代码,就是随便一个网站都能搜索到的client端的代码,我就毫不客气的复制了,谁叫我是菜鸟:
#include <stdio.h>
#include <sys/socket.h>
#include <unistd.h>
#include <sys/types.h>
#include <netinet/in.h>
#include <stdlib.h>
#include <stdio.h>
#include <stdlib.h>
#include <errno.h>
#include <string.h>
#include <sys/types.h>
#include <netinet/in.h>
#include <arpa/inet.h>
#include <sys/socket.h>
#include <sys/wait.h>
#include <unistd.h>
#include <netdb.h>
#include <time.h>
#define SERVER_PORT 20000 // define the defualt connect port id
#define CLIENT_PORT ((20001+rand())%65536) // define the defualt client port as a random port
#define BUFFER_SIZE 255
#define REUQEST_MESSAGE "welcome to connect the server./n"
void usage(char *name)
{
printf("usage: %s destinationIpAddr\n",name);
}
int main(int argc, char **argv)
{
int clifd,length = 0;
struct sockaddr_in servaddr,cliaddr;
socklen_t socklen = sizeof(servaddr);
char *serv_ip="192.168.1.235";
char buf[BUFFER_SIZE];
/* if (argc < 2)
{
usage(argv[0]);
exit(1);
}
*/
if ((clifd = socket(AF_INET,SOCK_STREAM,0)) < 0)
{
printf("create socket error!/n");
exit(1);
}
srand(time(NULL));//initialize random generator
bzero(&cliaddr,sizeof(cliaddr));
cliaddr.sin_family = AF_INET;
cliaddr.sin_port = htons(CLIENT_PORT);
cliaddr.sin_addr.s_addr = inet_addr("192.168.0.234");//htons(INADDR_ANY);
bzero(&servaddr,sizeof(servaddr));
servaddr.sin_family = AF_INET;
inet_aton(serv_ip/*argv[1]*/,&servaddr.sin_addr);
servaddr.sin_port = htons(SERVER_PORT);
//servaddr.sin_addr.s_addr = htons(INADDR_ANY);
if (bind(clifd,(struct sockaddr*)&cliaddr,sizeof(cliaddr))<0)
{
printf("bind to port %d failure!/n",CLIENT_PORT);
exit(1);
}
if (connect(clifd,(struct sockaddr*)&servaddr, socklen) < 0)
{
printf("can't connect to %s!/n",/*argv[1]*/serv_ip);
exit(1);
}
length = recv(clifd,buf,BUFFER_SIZE,0);
if (length < 0)
{
printf("error comes when recieve data from server %s!",/*argv[1]*/serv_ip);
exit(1);
}
printf("from server %s :/n/t%s ",/*argv[1]*/serv_ip,buf);
int rc;
rc=send(clifd,"some messages",strlen("some messages"),0);
if(rc < 0)
{
printf("error comes when recieve data from server %s!",/*argv[1]*/serv_ip);
exit(1);
}
close(clifd);
return 0;
}
标准的菜鸟格式,当然,我也是经过了编译,确认了代码的可执行(fedora6下),并且跟服务器交互正常。
一样的三步曲,不一样的曲折。
socket编程,常规的就是
1.socket()
2.bind()
3.connect()
成功之后,就是随意的发送,接收数据了。
只是,上面这三步,干了什么活,就把两个互不相干的IP链接起来,这么牛?