Chinaunix首页 | 论坛 | 博客
  • 博客访问: 1427034
  • 博文数量: 842
  • 博客积分: 12411
  • 博客等级: 上将
  • 技术积分: 5772
  • 用 户 组: 普通用户
  • 注册时间: 2011-06-14 14:43
文章分类

全部博文(842)

文章存档

2013年(157)

2012年(685)

分类: LINUX

2012-05-17 17:02:30

Normal 0 7.8 磅 0 2 false false false EN-US ZH-CN X-NONE MicrosoftInternetExplorer4 /* Style Definitions */ table.MsoNormalTable {mso-style-name:普通表格; mso-tstyle-rowband-size:0; mso-tstyle-colband-size:0; mso-style-noshow:yes; mso-style-priority:99; mso-style-qformat:yes; mso-style-parent:""; mso-padding-alt:0cm 5.4pt 0cm 5.4pt; mso-para-margin:0cm; mso-para-margin-bottom:.0001pt; mso-pagination:widow-orphan; font-size:10.5pt; mso-bidi-font-size:11.0pt; font-family:"Calibri","sans-serif"; mso-ascii-font-family:Calibri; mso-ascii-theme-font:minor-latin; mso-fareast-font-family:宋体; mso-fareast-theme-font:minor-fareast; mso-hansi-font-family:Calibri; mso-hansi-theme-font:minor-latin; mso-bidi-font-family:"Times New Roman"; mso-bidi-theme-font:minor-bidi; mso-font-kerning:1.0pt;} 服务器端和客户端实例

 

下面从服务器端完整地叙述一遍服务器端socket创建、监听、与客户端建立连接的过程。

要建立一个处理连接的服务器端程序,首先要调用socket函数创建一个socket,返回一个文件句柄fd,使以后对它的操作就象对普通文件设备一样读写。

由于是服务器端必须对一个端口进行监听其他机器的请求,所以接下去调用bind函数,传入刚才的fd,定义好地址和端口,由于是要接受来自任何host的连接所以应讲sin_addr赋为INADDR_ANY,port为你所设定的端口。

注意:这里的地址和端口是网络字节顺序,所以要调用htonl,htons完成主机字节顺序

到网络字节的转变

当服务器端的Socket对象绑定完成之后,服务器端必须建立一个监听的队列来接收客户端的连接请求。使用listen()函数使服务器端的Socket 进入监听状态,并设定可以建立的最大连接数(目前最大值限制为 5, 最小值为1)。该函数调用成功返回0,否则返回SOCKET_ERROR

服务器端的Socket调用完listen()后,如果此时客户端调用connect()函数提出连接申请的话,Server 端必须再调用accept() 函数,这样服务器端和客户端才算正式完成通信程序的连接动作。

整个过程就是socket->bind->listen->accpet->Read,write

(而对于客户端则是socket->connect->read,write

 

以下附一个简单的例子,实现功能:客户端程序A向服务器端程序B发送一个消息后,服务器将这个消息返回给客户端,在客户端及服务器端分别打印出这个消息。

服务器端代码:

#include

#include

#include

#include

#include

#include

#include

 

#define DEST_IP "127.0.0.1"

#define DEST_PORT 1316

#define MY_PORT 3490 

#define BACKLOG 2 

 

void main()

{

        int sockfd;

        int send_len;

        int recv_len;

        int new_fd;

        char buffer[1024];

        struct sockaddr_in my_addr;

        struct sockaddr_in other_addr;

        sockfd = socket(AF_INET,SOCK_STREAM,0);

        my_addr.sin_family = AF_INET;

        my_addr.sin_addr.s_addr = INADDR_ANY;//表示服务器可以接受任何客户端的请求

        my_addr.sin_port = htons(DEST_PORT);// htons(监听的端口)实现主机字节序到网络字节序的转换

 

        bind(sockfd, (struct sockaddr*)&my_addr,sizeof(my_addr));

        listen(sockfd,BACKLOG);

 

        while(1){

                new_fd = -1;

                socklen_t other_size = sizeof(struct sockaddr_in);

                new_fd = accept(sockfd,(struct sockaddr*)&other_addr,&other_size);

                recv_len = recv(new_fd, buffer, sizeof(buffer)-1, 0 );

               

                if( recv_len > 0 )

                {      

                        buffer[recv_len] = 0;

                        send(new_fd, buffer, strlen(buffer),0);

                        printf("%s\n",buffer);

                }

                close(new_fd);

        }

        close(sockfd);

}

客户端代码:

#include

#include

#include

#include

#include

#include

#include

 

int main(int agrc, char** argv)

{

        int   sock_cli;

        int   sock;

        struct   sockaddr_in   serv_addr;

        char buffer[1024];

        sock_cli=socket(AF_INET,SOCK_STREAM,0);

        bzero(&serv_addr,sizeof(serv_addr));

        serv_addr.sin_family=AF_INET;

        serv_addr.sin_port=htons(1316);

        serv_addr.sin_addr.s_addr=inet_addr("127.0.0.1");

        if( (sock=connect(sock_cli,(struct sockaddr *)&serv_addr,sizeof(struct sockaddr))) < 0 )

{

                return -1;

        }

        if( agrc != 2 )

                send(sock_cli, "testing", strlen("testing"), 0 );

        else

                send(sock_cli, argv[1], strlen(argv[1]),0);

 

        int recv_len = recv(sock_cli, buffer, sizeof(buffer)-1, 0 );

        buffer[recv_len] = 0;

        printf("%s\n",buffer);

       

        close(sock_cli);

 

}

 

阅读(914) | 评论(0) | 转发(1) |
0

上一篇:高级套接字系统调用

下一篇:线程基础

给主人留下些什么吧!~~