socket編程與利用進程進行多并行連接

jopen 9年前發布 | 11K 次閱讀 Socket

呈現一張基本的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; }</pre>
客戶端(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; }</pre>

  相關的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)</pre>

但是上述雖然滿足了基本的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");</pre>
二:  利用進程進行并行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; }</pre>

編程是一種快樂,享受代碼帶給我的樂趣!!!
來自:http://www.cnblogs.com/gongxijun/p/4592864.html

 本文由用戶 jopen 自行上傳分享,僅供網友學習交流。所有權歸原作者,若您的權利被侵害,請聯系管理員。
 轉載本站原創文章,請注明出處,并保留原始鏈接、圖片水印。
 本站是一個以用戶分享為主的開源技術平臺,歡迎各類分享!