呈现一张基本的socket阻塞式模型,如下图:

                    

 一: 对于一对一的进行C/S回射:

服务端(server.c):

 #include<unistd.h>
#include<stdio.h>
#include<string.h>
#include<stdlib.h>
#include<netinet/in.h>
#include<sys/socket.h>
#include<sys/types.h>
#include<error.h> #define ERR_EXIT(m) \
do{ \
perror(m); \
exit(); \
}while() int
main (void)
{
int sock, conn;
if ((sock = socket (PF_INET, SOCK_STREAM, )) < )
ERR_EXIT ("socket");
struct sockaddr_in sockaddr;
memset (&sockaddr, , sizeof (sockaddr));
sockaddr.sin_family = AF_INET;
sockaddr.sin_port = htons ();
sockaddr.sin_addr.s_addr = htonl (INADDR_ANY);
if (bind (sock, (struct sockaddr *) &sockaddr, sizeof (sockaddr)) < )
ERR_EXIT ("Bind");
if (listen (sock, SOMAXCONN) < )
ERR_EXIT ("Listen");
struct sockaddr_in client;
memset (&client, , sizeof (client));
socklen_t addrlen = sizeof (client);
if ((conn = accept (sock, (struct sockaddr *) &client, &addrlen)) < )
ERR_EXIT ("Accept");
char sed[], recv[];
while (fgets (sed, sizeof (sed), stdin) != NULL || == )
{
if (strlen (sed) > )
write (conn, sed, sizeof (sed));
if (read (conn, recv, sizeof (recv)) > )
{
fputs (recv, stdout);
if (strcmp (recv, "exit") == )
break;
write (conn, recv, sizeof (recv));
}
else
ERR_EXIT ("read...");
}
close (conn);
close (sock);
return ;
}

客户端(client.c):

 #include<unistd.h>
#include<stdio.h>
#include<string.h>
#include<error.h>
#include<netinet/in.h>
#include<stdlib.h>
#include<sys/socket.h>
#include<sys/types.h> #define ERR_EXIT( m ) \
do{ \
perror(m); \
exit(); \
}while(); int
main (void)
{
int socketid, conn; if ((socketid = socket (PF_INET, SOCK_STREAM, IPPROTO_TCP)) < )
ERR_EXIT ("socket"); struct sockaddr_in server_addr;
memset (&server_addr, , sizeof (server_addr)); server_addr.sin_family = AF_INET;
server_addr.sin_port = htons ();
server_addr.sin_addr.s_addr = inet_addr ("127.0.0.1");
if ((conn =
connect (socketid, (struct sockaddr *) &server_addr,
sizeof (server_addr))) < )
ERR_EXIT ("connect");
char sendbuf[], recivebuf[];
while (fgets (sendbuf, sizeof (sendbuf), stdin) != NULL)
{
write (socketid, sendbuf, sizeof (sendbuf));
read (socketid, recivebuf, sizeof (recivebuf));
fputs (recivebuf, stdout);
if (strcmp (recivebuf, "exit") == )
{
ERR_EXIT ("exit");
break;
}
}
close (conn);
close (socketid);
return ;
}

相关的makefile文件

 makefile文件:

 .SUFFIXES: .o.c
.PHONY: clean
.PHONY: start CC =gcc
SRC =server.c
OBJS =$(SRC:.c =.o)
BIN = Server start:
$(CC) -o $(BIN) $(OBJS) .o.c:
$(CC) -g -Wall $@ -c $<
clean:
rm -f $(OBJS)

但是上述虽然满足了基本的socket套路,但是当我们关闭服务可执行程序时,在开启就会出现地址被占用,解决此等问题,需再加上一个setsockopt()函数,对齐进行设定。

详细可以去查询man帮助(man  setsockopt)

代码:

  int on = ;
if (setsockopt (sock, SOL_SOCKET, SO_REUSEADDR, &on, sizeof (on)) < )
{
ERR_EXIT ("setsockopt");
} if (bind (sock, (struct sockaddr *) &sockaddr, sizeof (sockaddr)) < )
ERR_EXIT ("Bind");

  二:  利用进程进行并行socket阻塞式连接:

        客户端和makefile文件和上面一样,只是将socket的服务端,修改为调用进程来进行多并发连接即可!

服务端(server.c):

 #include<unistd.h>
#include<stdio.h>
#include<string.h>
#include<stdlib.h>
#include<netinet/in.h>
#include<sys/socket.h>
#include<sys/types.h>
#include<error.h> #define ERR_EXIT(m) \
do{ \
perror(m); \
exit(); \
}while() void
print (int conn){ char sed[], recv[];
while (fgets (sed, sizeof (sed), stdin) != NULL || == )
{
if (strlen (sed) > )
write (conn, sed, sizeof (sed));
if (read (conn, recv, sizeof (recv)) > )
{
fputs (recv, stdout);
if (strcmp (recv, "exit") == )
break;
write (conn, recv, sizeof (recv));
}
else
ERR_EXIT ("read...");
}
close (conn);
} int
main (void)
{
int sock, conn;
if ((sock = socket (PF_INET, SOCK_STREAM, )) < )
ERR_EXIT ("socket");
struct sockaddr_in sockaddr;
memset (&sockaddr, , sizeof (sockaddr));
sockaddr.sin_family = AF_INET;
sockaddr.sin_port = htons ();
sockaddr.sin_addr.s_addr = htonl (INADDR_ANY); int on = ;
if (setsockopt (sock, SOL_SOCKET, SO_REUSEADDR, &on, sizeof (on)) < )
{
ERR_EXIT ("setsockopt");
} if (bind (sock, (struct sockaddr *) &sockaddr, sizeof (sockaddr)) < )
ERR_EXIT ("Bind"); if (listen (sock, SOMAXCONN) < )
ERR_EXIT ("Listen"); struct sockaddr_in client;
memset (&client, , sizeof (client));
socklen_t addrlen = sizeof (client);
pid_t pid ; while ()
{
if((conn = accept (sock, (struct sockaddr *) &client, &addrlen)) < )
ERR_EXIT ("Accept");
pid = fork ();
if (pid == -)
ERR_EXIT ("fork");
else if (pid == ){
close (sock);
print (conn);
}
else
close (conn);
}
close (sock);
return ;
}

最新文章

  1. Android课程---关于数据存储的学习(3)之数据库和事务
  2. SQL Server : Browser服务
  3. Stanford机器学习笔记-6. 学习模型的评估和选择
  4. 为什么springMVC和Mybatis逐渐流行起来了?
  5. awk操作数组注意几点
  6. mac上安装Navicat Premium 破解版+汉化包
  7. C++ 标准库类型-String,Vector and Bitset
  8. [C#] 可空类型的实现原理
  9. QT 多线程程序设计【转】
  10. Unity 3D 进度条制作
  11. HUST 1351 Group
  12. 快速搭建一个本地的FTP服务器
  13. Jenkins简明入门(二) -- 利用Jenkins完成Python程序的build、test、deployment
  14. Effective C++ ——设计与声明
  15. Jmeter学习之-获取登录的oken值(1)
  16. linux shutdown命令以及参数详解
  17. 关于Python matplotlib显示汉字乱码问题
  18. Android Studio Ffmpeg
  19. mongodb-分组分页
  20. Action 中获取表单数据的三种方式

热门文章

  1. Nginx+Lua(OpenResty)开发高性能Web应用
  2. Spring+Mybatis+SpringMVC+Maven+MySql搭建实例
  3. 用 python 实现一个多线程网页下载器
  4. linux svn服务器svnserve 安装配置
  5. org.eclipse.jdi.TimeoutException: Timeout occurred while waiting for packet 421. occured resuming VM.
  6. CSS图片列表
  7. TTL
  8. Java 利用初学知识 写出自己的名字
  9. Linux命令大全----常用文件操作命令
  10. noi 2728 摘花生