socket编程与利用进程进行多并行连接
jopen
9年前
呈现一张基本的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(1); \ }while(0) int main (void) { int sock, conn; if ((sock = socket (PF_INET, SOCK_STREAM, 0)) < 0) ERR_EXIT ("socket"); struct sockaddr_in sockaddr; memset (&sockaddr, 0, sizeof (sockaddr)); sockaddr.sin_family = AF_INET; sockaddr.sin_port = htons (5528); sockaddr.sin_addr.s_addr = htonl (INADDR_ANY); if (bind (sock, (struct sockaddr *) &sockaddr, sizeof (sockaddr)) < 0) ERR_EXIT ("Bind"); if (listen (sock, SOMAXCONN) < 0) ERR_EXIT ("Listen"); struct sockaddr_in client; memset (&client, 0, sizeof (client)); socklen_t addrlen = sizeof (client); if ((conn = accept (sock, (struct sockaddr *) &client, &addrlen)) < 0) ERR_EXIT ("Accept"); char sed[1024], recv[1024]; while (fgets (sed, sizeof (sed), stdin) != NULL || 1 == 1) { if (strlen (sed) > 0) write (conn, sed, sizeof (sed)); if (read (conn, recv, sizeof (recv)) > 0) { fputs (recv, stdout); if (strcmp (recv, "exit") == 0) break; write (conn, recv, sizeof (recv)); } else ERR_EXIT ("read..."); } close (conn); close (sock); return 0; }
客户端(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(1); \ }while(0); int main (void) { int socketid, conn; if ((socketid = socket (PF_INET, SOCK_STREAM, IPPROTO_TCP)) < 0) ERR_EXIT ("socket"); struct sockaddr_in server_addr; memset (&server_addr, 0, sizeof (server_addr)); server_addr.sin_family = AF_INET; server_addr.sin_port = htons (5528); server_addr.sin_addr.s_addr = inet_addr ("127.0.0.1"); if ((conn = connect (socketid, (struct sockaddr *) &server_addr, sizeof (server_addr))) < 0) ERR_EXIT ("connect"); char sendbuf[1024], recivebuf[1024]; while (fgets (sendbuf, sizeof (sendbuf), stdin) != NULL) { write (socketid, sendbuf, sizeof (sendbuf)); read (socketid, recivebuf, sizeof (recivebuf)); fputs (recivebuf, stdout); if (strcmp (recivebuf, "exit") == 0) { ERR_EXIT ("exit"); break; } } close (conn); close (socketid); return 0; }
相关的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 = 1; if (setsockopt (sock, SOL_SOCKET, SO_REUSEADDR, &on, sizeof (on)) < 0) { ERR_EXIT ("setsockopt"); } if (bind (sock, (struct sockaddr *) &sockaddr, sizeof (sockaddr)) < 0) 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(1); \ }while(0) void print (int conn){ char sed[1024], recv[1024]; while (fgets (sed, sizeof (sed), stdin) != NULL || 1 == 1) { if (strlen (sed) > 0) write (conn, sed, sizeof (sed)); if (read (conn, recv, sizeof (recv)) > 0) { fputs (recv, stdout); if (strcmp (recv, "exit") == 0) 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, 0)) < 0) ERR_EXIT ("socket"); struct sockaddr_in sockaddr; memset (&sockaddr, 0, sizeof (sockaddr)); sockaddr.sin_family = AF_INET; sockaddr.sin_port = htons (5528); sockaddr.sin_addr.s_addr = htonl (INADDR_ANY); int on = 1; if (setsockopt (sock, SOL_SOCKET, SO_REUSEADDR, &on, sizeof (on)) < 0) { ERR_EXIT ("setsockopt"); } if (bind (sock, (struct sockaddr *) &sockaddr, sizeof (sockaddr)) < 0) ERR_EXIT ("Bind"); if (listen (sock, SOMAXCONN) < 0) ERR_EXIT ("Listen"); struct sockaddr_in client; memset (&client, 0, sizeof (client)); socklen_t addrlen = sizeof (client); pid_t pid ; while (1) { if((conn = accept (sock, (struct sockaddr *) &client, &addrlen)) < 0) ERR_EXIT ("Accept"); pid = fork (); if (pid == -1) ERR_EXIT ("fork"); else if (pid == 0){ close (sock); print (conn); } else close (conn); } close (sock); return 0; }
编程是一种快乐,享受代码带给我的乐趣!!!
来自:http://www.cnblogs.com/gongxijun/p/4592864.html