Chinaunix首页 | 论坛 | 博客
  • 博客访问: 928615
  • 博文数量: 376
  • 博客积分: 154
  • 博客等级: 入伍新兵
  • 技术积分: 1558
  • 用 户 组: 普通用户
  • 注册时间: 2011-10-13 08:42
文章分类

全部博文(376)

文章存档

2014年(11)

2013年(88)

2012年(260)

2011年(17)

分类:

2011-12-19 10:58:42

原文地址:简单linux socket编程 作者:long_java



以下是unix网络编程的函数说明


'socket' Function
To perform network I/O, the first thing a process must do is call the socket function,
specifying the type of communication protocol desired (TCP using IPv4, UDP using
IPv6, Unix domain stream protocol, etc.).
#include
int socket (int family, int type, int protocol);
Returns: non-negative descriptor if OK, -1 on error
    

具体参数如下



'connect' Function
The connect function is used by a TCP client to establish a connection with a TCP
server.
#include
int connect(int sockfd, const struct sockaddr *servaddr, socklen_t addrlen);
Returns: 0 if OK, -1 on error
其中struct sockaddr
是一个结构体。
struct sockaddr_in { sa_family_t sin_family; /* address family: AF_INET */ in_port_t sin_port; /* port in network byte order */ struct in_addr sin_addr; /* internet address */ }; /* Internet address. */ struct in_addr { uint32_t s_addr; /* address in network byte order */ };



'bind' Function
#include
int bind (int sockfd, const struct sockaddr *myaddr, socklen_t addrlen);
Returns: 0 if OK,-1 on error



'listen' Function
#include
#int listen (int sockfd, int backlog);
Returns: 0 if OK, -1 on error



'accept' Function
#include
int accept (int sockfd, struct sockaddr *cliaddr, socklen_t *addrlen);
Returns: non-negative descriptor if OK, -1 on error


This function returns up to three values: an integer return code that is either a new
socket descriptor or an error indication, the protocol address of the client process
(through the cliaddr pointer), and the size of this address (through the addrlen
pointer). If we are not interested in having the protocol address of the client returned,
we set both cliaddr and addrlen to null pointers.


'close' Function
#include
int close (int sockfd);
Returns: 0 if OK, -1 on error


以下为一个简单的c/s模式程序。
//服务器端
//server.c
#include
#include
#include
#include
#include
#include
#include
#define MAXLINE 4096
int main(int argc ,char ** argv)
{
    int listenfd,connfd;
    char buffer[4096];
    char  sendline[4096];
    struct sockaddr_in server_sockaddr;

    if((listenfd=socket(AF_INET,SOCK_STREAM,0))<0)
    {
      printf("socket");
      exit(0);
    }

   printf("The listenfd is %d\n",listenfd);

    memset(&server_sockaddr,0,sizeof(server_sockaddr));

    server_sockaddr.sin_family=AF_INET;
    server_sockaddr.sin_port=htons(4321);
    server_sockaddr.sin_addr.s_addr=INADDR_ANY;

    if(bind(listenfd,(struct sockaddr *)&server_sockaddr,sizeof(server_sockaddr))==-1)
    {
      printf("listen ");
      exit(0);
    }


     if(listen(listenfd,10)==-1)
    {
    printf("listen ");
    exit(0);
    }

    while(1)
    {

    if( (connfd = accept(listenfd, (struct sockaddr*)NULL, NULL)) == -1)

     //if((connfd=accept(listenfd,(struct sockaddr *)NULL,NULL))==-1)
     {
       printf("connet...");

       printf("%d\n",connfd);
       continue;
     }


      printf("The connfd is %d\n",connfd);
      memset(buffer,0,sizeof(buffer));
      if(recv(connfd,buffer,MAXLINE,0)<0)
      {
        printf("recv error\n");
        exit(0);
      }



     printf("%s",buffer);






      close(connfd);

    }

    close(listenfd);
    return 0;

}


//客户端
//client.c
#include
#include
#include
#include
#include
#include
#include

 #define MAXLINE 4096

int main(int argc, char ** argv)
{
    int sockfd;
    char  sendline[4096];

    struct sockaddr_in servaddr;


    if(argc!=2)
    {
        printf("./cilent ");
        exit(0);
    }

    if((sockfd=socket(AF_INET,SOCK_STREAM,0))==-1)
    {
        perror("socket");
        exit(0);
    }
    printf("socketfd is %d\n",sockfd);
    memset(&servaddr, 0, sizeof(servaddr));
    servaddr.sin_family=AF_INET;
    servaddr.sin_port = htons(4321);
    if(inet_pton(AF_INET,argv[1],&servaddr.sin_addr)<0)
    {
        perror("inet_pton");
        exit(0);
    }


    if(connect(sockfd,(struct sockaddr *)&servaddr,sizeof(servaddr))==-1)
    {
        perror("connect");
        exit(0);
    }

    printf("send message to server\n");
    fgets(sendline,sizeof(sendline),stdin);


    if(send(sockfd,sendline,strlen(sendline),0)==-1)
    {
        perror("send");
        exit(0);
    }






    close(sockfd);

    return 0;

}


运行程序

客户端:
long@ubuntu:~/longjava/coding/chapter6$ ./client 127.0.0.1
socketfd is 3
send message to server
hello world


服务器:
long@ubuntu:~/longjava/coding/chapter6$ ./server
The listenfd is 3
The connfd is 4
hello world


分析该程序只是简单的一个示例。服务器每次之能处理一个客户。一开始,服务器就处于阻塞状态。当accept一个客户时候服务器开始继续跑,等到      if(recv(connfd,buffer,MAXLINE,0)<0)这句时候又开始阻塞。等待客户的输入。实际开发时可以采用多种方法来优化。例如,非阻塞I/O,I/O多路复用,信号驱动,异步I/O方式来解决多个客户的通信。另外,还可以利用多进程或者多线程来解决多客户。多客户的socket通信是一门学问,值得我们好好研究。

参考:
《嵌入算应用程序设计》
  《unix网络编程》
http://www.cnblogs.com/skynet/archive/2010/12/12/1903949.html
阅读(625) | 评论(0) | 转发(0) |
给主人留下些什么吧!~~