分析一个socket通信: server/client
分析一个socket通信: server/client1
server
1. 创建一个server_socket文件,并绑定端口,然后监听端口 (socket, bind, listen)
2. 查询该端口是否有客户端的连接:
while(1)
{
查询这个端口是否有来自client的消息;(accept)// accept: input is server_socket_fd ; ret value is client_socket_fd
如果有,返回client_socket_fd, 并把消息读出来 (rcv from client_socket_fd); 当然这个时候server也可以send to client_socket.
}
client
1. 创建一个client_socket文件,绑定端口和server ip,然后通过这个socket去和server的socket连接起来 (socket, connect);
2. 连接成功后,client往client_socket写东西(send to client_socket_fd). 当然这个时候client也可以rcv from client_socket.
client_socket文件的作用是client和server之间的一个通信管道。
debug代码:
//client:
#include <stdio.h>
#include <stdlib.h>
#include <unistd.h>
#include <string.h>
#include <fcntl.h>
#include <sys/types.h> /* See NOTES */
#include <sys/socket.h>
#include <netinet/in.h>
#include <arpa/inet.h>
#include <errno.h> #define N 128 typedef struct sockaddr SA; extern void show_time(void); int main(int argc, char *argv[])
{
int sockfd, fd, nbyte;
char command[];
struct sockaddr_in server_addr; if (argc < )
{
printf("Usage : %s <server_ip> : <port>\n", argv[]);
exit(-);
} memset(&server_addr, , sizeof(server_addr));
server_addr.sin_family = PF_INET;
server_addr.sin_port = htons(atoi(argv[]));
server_addr.sin_addr.s_addr = inet_addr(argv[]); while ( )
{
printf("<client> ");
fgets(command, , stdin);
command[strlen(command)-] = '\0'; // overwrite the '\n' if ((sockfd = socket(PF_INET, SOCK_STREAM, )) < )
{
printf("fail to get\n");
return;
}
printf("socket\n");show_time();
if (connect(sockfd, (SA *)&server_addr, sizeof(server_addr)) < )
{
printf("fail to connect server\n");
return;
}
printf("send\n");show_time();
send(sockfd, command, strlen(command)+, );
printf("send over\n");show_time();
close(sockfd);
} return ;
}
//break client.c:41
//server:
#include <stdio.h>
#include <stdlib.h>
#include <unistd.h>
#include <string.h>
#include <fcntl.h>
#include <dirent.h>
#include <sys/types.h> /* See NOTES */
#include <sys/socket.h>
#include <netinet/in.h>
#include <arpa/inet.h>
#include <errno.h> #define N 128 typedef struct sockaddr SA;
extern void show_time(void); int main(int argc, char *argv[])
{
int listenfd, connfd;
char buf[N];
struct sockaddr_in server_addr; // XXX:step 1 int socket(int domain, int type, int protocol);
if ((listenfd = socket(PF_INET, SOCK_STREAM, )) < )
{
fprintf(stderr, "fail to socket : %s\n", strerror(errno));
exit(-);
}
#ifdef _DEBUG_
printf("socket is %d\n", listenfd);
#endif // XXX:step 2 int bind(int sockfd, const struct sockaddr *serv_addr, socklen_t addrlen);
memset(&server_addr, , sizeof(server_addr));
server_addr.sin_family = PF_INET;
server_addr.sin_port = htons();
server_addr.sin_addr.s_addr = htonl(INADDR_ANY);
if (bind(listenfd, (SA *)&server_addr, sizeof(server_addr)) < )
{
perror("fail to bind");
exit(-);
} listen(listenfd, );
static int counter = ;
while ( )
{
if ((connfd = accept(listenfd, NULL, NULL)) < )
{
perror("fail to accept"); show_time();
break;
}else{
printf("a connect from client accepted, counter = %d\n", counter++); show_time();
}
recv(connfd, buf, N, );
printf("recvd from client\n"); show_time();
send(connfd, "", , );
printf("sent to client\n"); show_time();
close(connfd);
} return ;
}
调试:
gcc -g client.c show_time.c -o client
gcc -g server.c show_time.c -o server
1. 打断点:
//break client.c:41
2. 跑server
3. 单步跑client,
当line47跑完 if (connect(sockfd, (SA *)&server_addr, sizeof(server_addr)) < 0) 的时候,
server打印“a connect from client accepted, counter = 0”
if ((connfd = accept(listenfd, NULL, NULL)) < )
{
perror("fail to accept"); show_time();
break;
}else{
printf("a connect from client accepted, counter = %d\n", counter++); show_time();
}
当line53跑完 send(sockfd, command, strlen(command)+1, 0) 的时候,
server打印 ”recvd from client “
recv(connfd, buf, N, );
printf("recvd from client\n"); show_time();
上面的实验说明了:
socket通信的几个函数接口之间的关系和时序。accept阻塞地等待client的connect接入;recv阻塞地等待client send的数据。
分析一个socket通信: server/client的更多相关文章
- Android简单实现Socket通信,client连接server后,server向client发送文字数据
案例实现的是简单的Socket通信,当client(Androidclient)连接到指定server以后,server向client发送一句话文字信息(你能够拓展其他的了) 先看一下服务端程序的实现 ...
- [001]socket通信--server和client实现迭代的简单例子
server端: #include<stdio.h> #include<stdlib.h> #include<string.h> #include<unist ...
- [000]socket通信--server和client实现的简单例子
在C语言中就学过scanf和printf,其实理解socket就跟这两个输入输出差不多,只不过是信息的传输而已. 1.TCP服务器端(server)的默认函数调用顺序: 按照上述的调用顺序,我们可以来 ...
- (OK) Linux epoll模型—socket epoll server client chat
http://www.cnblogs.com/venow/archive/2012/11/30/2790031.html http://blog.csdn.net/denkensk/article/d ...
- C# Socket TCP Server & Client & nodejs client
要调试公司某项目里的一个功能,因为要准备测试环境,趁这个机会重温了一下Socket(全还给老师了 -_-#),做个备份. C# Server static void Main(string[] arg ...
- libevent 实现的socket 通信 server以及解决找不到动态库的方法
注: client 个人觉得没必要用 libvent来实现就没写 注:由于 涉及到回调函数的使用 如有疑惑的可以先去了解回调函数的实现机理 先来说一下 libevent主要是干啥的 : 内部封装了 s ...
- 调试一个socket通信bug的心理过程和反思
背景交代.最近在玩lua的服务端编码, 有项目A,B,AB都是同一个模子的.我手上有A的winsocket客户端和服务端的代码,B项目早期的一份linux下的lua client.服务端.客户端都是L ...
- AgileEAS.NET SOA 中间件平台.Net Socket通信框架-简单例子-实现简单的服务端客户端消息应答
一.AgileEAS.NET SOA中间件Socket/Tcp框架介绍 在文章AgileEAS.NET SOA 中间件平台Socket/Tcp通信框架介绍一文之中我们对AgileEAS.NET SOA ...
- Socket通信的Python实现
Python中实现socket通信,socket通信的服务端比较复杂,而客户端非常简单,所以客户端基本上都是用sockct模块实现,而服务 端用有很多模块可以使用.下面就说一下服务端可使用的模块. 模 ...
随机推荐
- < high performance web sites > 阅读小记
high performance web sites 1,减少HTTP请求数 (1)图片加载使用image maps 或者 CSS Sprite (2)使用非http协议,如(ftp:, file: ...
- Java-多线程的实现与启动
class mythread extends Thread //多线程的启动 { private String name; public mythread(String name) { t ...
- 搜狗2015校园招聘javaproject师面经
面试时看到了我的笔试题.真是慘不忍睹啊. . 1. 问回去有没有研究一下笔试题 木有,果断后面悲剧了 2. 解释一下笔试的一道选择题: 下列哪种操作可能带来死锁? A: lock(m1) lock(m ...
- 详解iOS开发之自定义View
iOS开发之自定义View是本文要将介绍的内容,iOS SDK中的View是UIView,我们可以很方便的自定义一个View.创建一个 Window-based Application程序,在其中添加 ...
- LKD3
第三章 进程1. Unix操作系统的抽象:进程和文件2. 进程包括两个因素:可运行代码,和资源(打开的文件,挂起的信号,内核内部数据,处理器状态,地址空间)3. 线程是进程中活动的对象.4. 线程有独 ...
- 在Office Outlook 2013中收发QQ邮件
选择手动配置 选择第三项 点击More Settings,在Outgoing Server 勾选 如下 确认后,按下一步完成配置,此时会弹出对话框进行邮件发送测试.
- ClassLoader简单介绍
要理解ClassLoader,我们可以通过what.how两个方面来解释 一.what:什么事ClassLoader? 1.ClassLoader可以是将class文件加载到JVM方法区. 2.Cla ...
- Servlet学习的两个案例之网站访问次数的统计
一.统计次数的Servlet源码 package com.shanrengo; import java.io.IOException; import javax.servlet.ServletCont ...
- mysql root密码重置
1.修改my.cnf #位置一般是 /etc/my.cnf 2.重启mysql服务 service mysqld restart 3.进入mysql mysql -uroot -p 然后直接回车 4. ...
- How do I Find Out Linux CPU Utilization?
From:http://www.cyberciti.biz/tips/how-do-i-find-out-linux-cpu-utilization.html Whenever a Linux sys ...