很早的一段时间,看了APUE和UNPv1了解了网络编程,但是但是只是看而已,没有具体的实践,趁现在没有什么事做,就来实践了解一下网络编程。写博客保存下来,方便以后用到的时候可以查到。

  此次的聊天程序是迭代开发的。就是一步一步的修改成不同功能的聊天程序。

  服务器server和客户端client

  

  一对一,server和client是每人一句话聊天

  讲解几个函数gethostbyname(),这个函数以前讲过就不多说了。

  socket函数

  #include <sys/socket.h>

  int socket(int domain, int type, int protocol);    //返回值:若成功则返回文件(套接字)描述符,若出错则返回-1

  connect函数

  #include <sys/socket.h>

  int connect(int sockfd, const struct sockaddr *addr, socklen_t len);   //返回值:若成功则返回0,若出错则返回-1

  bind函数

  #include <sys/socket.h>

  int bind(int sockfd, const struct sockaddr *addr, socklen_t len);   //返回值:若成功则返回0,若出错则返回-1

  listen函数

  #include <sys/socket.h>

  int listen(int sockfd, int backlog);  //返回值:若成功则返回0,若出错则返回-1,backlog表示连接请求数量

  accept函数

  #include <sys/socket.h>

  int accept(int socdfd, struct sockaddr *restrict addr, socklen_t * restrict len); //若成功则返回文件(socket套接字)描述符,若出错则返回-1

  recv函数

  #include <sys/socket.h>

  ssize_t recv(int sockfd, void *buf, size_t nbytes, int flags);  //返回值:以字节计数的消息长度,若无可用消息或对方已经按序结束则返回0,若出错则返回-1

  send函数

  #include <sys/socket.h>

  ssize_t send(int sockfd, const void *buf, size_t nbytes, int flags);  //返回值:若成功则返回发送的字节数,若出错则返回-1

  fgets函数

  #include <stdio.h>

  char *fgets(char *s, int size, FILE *stream);

  介绍完函数后,就直接贴出代码。

  client.c

 #include <stdio.h>
#include <stdlib.h>
#include <errno.h>
#include <string.h>
#include <netdb.h> //for gethostbyname
#include <sys/types.h>
#include <sys/socket.h>
#include <netinet/in.h>
#include <arpa/inet.h> #define MAX_BUF 4096
#define SERVER_PORT 12138 int main(int argc,char *argv[])
{
int sockfd;//socket
char sendBuf[MAX_BUF],recvBuf[MAX_BUF];
int sendSize,recvSize;//用于记录记录发送和接收到数据的大小
struct hostent * host;
struct sockaddr_in servAddr;
char username[];
char * p; if(argc != )
{
perror("use: ./client [hostname] [username]");
exit(-);
}
p=username;
strcpy(p,argv[]);
printf("username:%s\n",username);
host=gethostbyname(argv[]);
if(host==NULL)
{
  perror("fail to get host by name.");
exit(-);
}
printf("Success to get host by name ...\n"); //创建socket
if((sockfd=socket(AF_INET,SOCK_STREAM,))==-)
{
  perror("fail to establish a socket");
  exit();
}
printf("Success to establish a socket...\n"); /*init sockaddr_in*/
servAddr.sin_family=AF_INET;
servAddr.sin_port=htons(SERVER_PORT);
servAddr.sin_addr=*((struct in_addr *)host->h_addr);
bzero(&(servAddr.sin_zero),); /*connect the socket*/
if(connect(sockfd,(struct sockaddr *)&servAddr,sizeof(struct sockaddr_in))==-)
{
  perror("fail to connect the socket");
  exit();
}
printf("Success to connect the socket...\n"); //send-recv
while()
{
printf("Input:");
fgets(sendBuf,MAX_BUF,stdin);
send(sockfd,sendBuf,strlen(sendBuf),);
memset(sendBuf,,sizeof(sendBuf));
recv(sockfd,recvBuf,MAX_BUF,);
printf("Server:%s\n",recvBuf);
memset(recvBuf,,sizeof(recvBuf));
} return ;
}

  server.c

 #include <stdio.h>
#include <stdlib.h>
#include <errno.h>
#include <string.h>
#include <netdb.h>
#include <sys/types.h>
#include <sys/socket.h>
#include <sys/time.h>
#include <sys/un.h>
#include <sys/ioctl.h>
#include <sys/wait.h>
#include <netinet/in.h>
#include <arpa/inet.h> #define SERVER_PORT 12138
#define BACKLOG 20
#define MAX_CON_NO 10
#define MAX_DATA_SIZE 4096 int main(int argc,char *argv[])
{
struct sockaddr_in serverSockaddr,clientSockaddr;
char sendBuf[MAX_DATA_SIZE],recvBuf[MAX_DATA_SIZE];
int sendSize,recvSize;
int sockfd,clientfd;
int on=;
int sinSize=;
char username[]; if(argc != )
{
printf("usage: ./server [username]\n");
exit();
}
strcpy(username,argv[]);
printf("username:%s\n",username); /*establish a socket*/
if((sockfd = socket(AF_INET,SOCK_STREAM,))==-)
{
perror("fail to establish a socket");
exit();
}
printf("Success to establish a socket...\n"); /*init sockaddr_in*/
serverSockaddr.sin_family=AF_INET;
serverSockaddr.sin_port=htons(SERVER_PORT);
serverSockaddr.sin_addr.s_addr=htonl(INADDR_ANY);
bzero(&(serverSockaddr.sin_zero),); setsockopt(sockfd,SOL_SOCKET,SO_REUSEADDR,&on,sizeof(on)); /*bind socket*/
if(bind(sockfd,(struct sockaddr *)&serverSockaddr,sizeof(struct sockaddr))==-)
{
perror("fail to bind");
exit();
}
printf("Success to bind the socket...\n"); /*listen on the socket*/
if(listen(sockfd,BACKLOG)==-)
{
perror("fail to listen");
exit();
} /*accept a client's request*/
if((clientfd=accept(sockfd,(struct sockaddr *)&clientSockaddr, &sinSize))==-)
{
perror("fail to accept");
exit();
}
printf("Success to accpet a connection request...\n");
printf(" %s join in!\n",inet_ntoa(clientSockaddr.sin_addr));
while()
{
/*receive datas from client*/
if((recvSize=recv(clientfd,recvBuf,MAX_DATA_SIZE,))==-)
{
perror("fail to receive datas");
exit();
}
printf("%s\n",recvBuf);
memset(recvBuf,,MAX_DATA_SIZE); /*send datas to client*/
printf("Server:");
fgets(sendBuf,MAX_DATA_SIZE,stdin);
if((sendSize=send(clientfd,sendBuf,strlen(sendBuf),))!=strlen(sendBuf))
{
perror("fail to send datas");
exit();
}
printf("Success to send datas\n");
memset(sendBuf,,MAX_DATA_SIZE);
} return ;
}

  这些代码都比较简单,详细的讲解网上都有,这里就不多说了。

  

  本文地址: http://www.cnblogs.com/wunaozai/p/3870156.html

Socket网络编程--聊天程序(1)的更多相关文章

  1. Socket网络编程--聊天程序(9)

    这一节应该是聊天程序的最后一节了,现在回顾我们的聊天程序,看起来还有很多功能没有实现,但是不管怎么说,都还是不错的.这一节我们将讲多服务器问题(高大上的说法就是负载问题了.)至于聊天程序的文件发送(也 ...

  2. Socket网络编程--聊天程序(8)

    上一节已经完成了对用户的身份验证了,既然有了验证,那么接下来就能对不同的客户端进行区分了,所以这一节讲实现私聊功能.就是通过服务器对客户端的数据进行转发到特定的用户上, 实现私聊功能的聊天程序 实现的 ...

  3. Socket网络编程--聊天程序(6)

    这一小节将增加一个用户的结构体,用于保存用户的用户名和密码,然后发给服务器,然后在服务器进行判断验证.这里就有一个问题,以前讲的就是发送字符串是使用char类型进行传输,然后在服务器进行用同样是字符串 ...

  4. Socket网络编程--聊天程序(7)

    接上一小节,本来是计划这一节用来讲数据库的增删改查,但是在实现的过程中,出现了一点小问题,也不是技术的问题,就是在字符界面上比较不好操作.比如要注册一个帐号,就需要弄个字符界面提示,然后输入数字表示选 ...

  5. Socket网络编程--聊天程序(3)

    上一小节,已经讲到可以每个人多说话,而且还没有限制,简单的来说,我们已经完成了聊天的功能了,那么接下来我们要实现什么功能呢?一个聊天程序至少应该支持一对多的通讯吧,接下来就实现多个客户端往服务器发送数 ...

  6. Socket网络编程--聊天程序(4)

    上一小节讲到可以实现多客户端与服务器进行通讯,对于每一个客户端的连接请求,服务器都要分配一个进程进行处理.对于多用户连接时,服务器会受不了的,而且还很消耗资源.据说有个select函数可以用,好像还很 ...

  7. Socket网络编程--聊天程序(5)

    上一小节我们讲了使用select来避免使用多进程的资源浪费问题.上次只是实现了从多个客户端发送数据给服务器端,接下来就要实现从服务器端发送数据给各个客户端. 使用select多路转换处理聊天程序2 c ...

  8. Socket网络编程--聊天程序(2)

    上一节简单如何通过Socket创建一个连接,然后进行通信.只是每个人只能说一句话.而且还是必须说完才会接收到信息,总之是很不方便的事情.所以这一小节我们将对上一次的程序进行修改,修改成每个人可以多说话 ...

  9. Socket网络编程--小小网盘程序(5)

    各位好呀!这一小节应该就是这个小小网盘程序的最后一小节了,这一节将实现最后的三个功能,即列出用户在服务器中的文件列表,还有删除用户在服务器中的文件,最后的可以共享文件给好友. 列出用户在服务器中的文件 ...

随机推荐

  1. POI搜索简介

    用户输入——用户输出-----------------------------------------------------------而POI搜索引擎,需要做的就是拿到输入条件,给出用户比较满意的 ...

  2. vs2017下发现解决python运行出现‘No module named "XXX""的解决办法

    对于使用vs2017开发python程序无疑发现,在解决方案资源管理器中设置把两个xxx.py,yyy.py文件都设置为启动文件,然后分别在vs2017这个IDE下运行这个两个文件在项目工程中运行,发 ...

  3. idea模板注释

    类文件头部的注释 #if (${PACKAGE_NAME} && ${PACKAGE_NAME} != "")package ${PACKAGE_NAME};#en ...

  4. 用js来实现那些数据结构03(数组篇03-排序及多维数组)

    终于,这是有关于数组的最后一篇,下一篇会真真切切给大家带来数据结构在js中的实现方式.那么这篇文章还是得啰嗦一下数组的相关知识,因为数组真的太重要了!不要怀疑数组在JS中的重要性与实用性.这篇文章分为 ...

  5. 【Java】同步阻塞式(BIO)TCP通信

    TCP BIO 背景 网络编程的基本模型是Clien/Server模型,也就是两个进程之间进行相互通信,其中服务端提供位置信息(绑定的IP地址和监听端口),客户端通过连接操作向服务端监听的地址发起连接 ...

  6. html/css实现阴影蒙版覆盖原网页并显示浮框的功能

    在提供用户修改资料/密码等功能的时候,往往希望给用户这样的使用体验,在不跳转,不弹框的情况下完成对这些功能的操作. 这可以通过一种效果来实现,在同一页面下阴影覆盖整个当前网页并使得原网页中元素无法使用 ...

  7. Web大前端面试题-Day7

    1. 你能描述一下渐进增强和优雅降级之间的不同吗? 定义: 优雅降级(graceful degradation): 一开始就构建站点的完整功能, 然后针对浏览器测试和修复 渐进增强(progressi ...

  8. 3682: Phorni 后缀平衡树 线段树

    国际惯例的题面: 考虑如果没有强制在线我们能怎么水掉这个题,先构造出字符串,各种方法求一下后缀数组,然后线段树维护区间rank最小的位置即可.然而他要求强制在线,支持插入后缀,并比较后缀大小(求ran ...

  9. (华中科大)江南雨烟 C++ STL 专栏

    本文转载来自,华中科技大学江南雨烟的C/C++专栏部分STL剖析文章,以作学习之用. [1]  [C++ STL学习之一]容器的共通能力和共通操作总结 [2]  [C++ STL学习之二]容器vect ...

  10. Minor GC 与Full GC有什么不一样

    新生代GC(Minor GC):指发生在新生代的垃圾收集动作,因为java对象大多都具备朝生夕灭的特性,所以Minor GC非常频繁,一般回收速度也非常快 老年代GC(Major GC/Full GC ...