C語言Socket程式設計(計算機網路作業)

weixin_34377065發表於2014-05-05

最近我計算機網路課程要做作業了,沒辦法跟著老師一步一步的寫C語言的程式碼,使用的計算就是Socket通訊傳送訊息;程式碼實現的功能很簡單,客戶端向伺服器端傳送訊息,伺服器端接收客戶端發來的訊息,並且輸出顯示到螢幕上;程式碼中的每個socket方法的返回值都應該做判斷出錯情況,例如:建立SOCKET的建立的時候s控制程式碼(或物件),需要判斷返回值是否為INVALID_SOCKET,以及socket的所有操作的返回值是否為SOCKET_ERROR,以保證程式的穩定性,這裡只是測試程式碼。

老師是錄製的視訊講解的,其他其中使用的到的方法要求我們自己去查相關的MSDN資料庫,如果有不懂的,就自己上網查。

伺服器端接收程式碼:

#include <Winsock2.h>
#pragma comment(lib,"Ws2_32.lib")
#include <stdio.h>
#include <memory.h>

void main()
{
WSAData wsd;
WSAStartup(MAKEWORD(2,0),&wsd);

SOCKET s =NULL;
s=socket(AF_INET,SOCK_STREAM,IPPROTO_TCP);
struct sockaddr_in ch;
memset(&ch,0,sizeof(ch));
ch.sin_family=AF_INET;
ch.sin_addr.s_addr=INADDR_ANY;
ch.sin_port=htons(1041);
int b=bind(s,(struct sockaddr *) &ch,sizeof(ch));
#define QUEUE_SIZE 5
int l=listen(s,QUEUE_SIZE);
printf("正在監聽本機的1041埠!\n");
SOCKET sc=accept(s,0,0);
printf("客戶端已經連線到本機的1041埠!\n");
#define BUF_SIZE 4096
int receByt=0;
while(1)
{
char buf[BUF_SIZE];
receByt=recv(sc,buf,BUF_SIZE,0);
buf[receByt]='\0';
if(receByt>0)
{
printf("接收的訊息是:%s\n",buf);
}
else
{
printf("接收訊息結束!");
break;
}

}
int ic=closesocket(sc);
int is=closesocket(s);

}

======================================================
客戶端傳送的程式碼:

#include <Winsock2.h>
#pragma comment(lib,"Ws2_32.lib")
#include <stdio.h>
#include <memory.h>
#include <string.h>

void main()
{
WSAData wsd;
WSAStartup(MAKEWORD(2,0),&wsd);

SOCKET s =NULL;
s=socket(AF_INET,SOCK_STREAM,IPPROTO_TCP);
struct sockaddr_in ch;
memset(&ch,0,sizeof(ch));
ch.sin_family=AF_INET;
ch.sin_addr.s_addr=inet_addr("127.0.0.1");
ch.sin_port=htons(1041);

int c=connect(s,(struct sockaddr *) &ch,sizeof(ch));
printf("已經連線到伺服器的1041埠!現在可以向伺服器傳送訊息了!\n");
#define BUF_SIZE 4096
char info[1024],buf[BUF_SIZE];

while(1)
{
gets(info);
if(info[0]=='\0')
break;
strcpy(buf,info);
int nsend=send(s,buf,strlen(buf),0);

}
int ic=closesocket(s);
}

========================================================================

程式程式碼經過了優化,並且整合多執行緒,把接收和傳送放到同一個檔案中,使用引數模式呼叫傳送和接收模組。增加了建立SOCKET的建立的時候s控制程式碼(或物件)判斷返回值是否為INVALID_SOCKET,以及socket的bind操作的返回值是否為SOCKET_ERROR,其他socket的操作應該也判斷SOCKET_ERROR,以保證程式的穩定性,這裡只是測試程式碼就不去寫這麼多了,剩下的就由你個人發揮。

#include <Winsock2.h>
#pragma comment(lib,"Ws2_32.lib")
#include <stdio.h>
#include <memory.h>
#include <string.h>
#include <pthread.h>


void Receive();
void Send();
void creatThread();

SOCKET s =NULL;
pthread_t t[1000];
int threadCount=0;

void main(int argc,char* argv[])
{
    printf("本程式製作人學號:713901040041\n");
    printf("程式說明:伺服器端和客戶端為同一個程式,請使用不同的引數執行.\n");
    printf("接收程式請使用 r引數;傳送程式請使用 s引數。\n");
    //printf("len : %d\n", argc);
    //printf("count %d\n",argc);
    //printf("value: %s\n",argv[1]);
    //printf("%d",argv[1][0]=='r');

    if(argc<=1)
    {
        printf("please input program arguments ...\n");
        exit(0);
    }
    if(argc>1 && argv[1][0]=='r')
    {
        printf("run receive ...\n");
        Receive();
    }
    if(argc>1 && argv[1][0]=='s')
    {
        printf("run send ...\n");
        Send();
    }
}


void* receiveWork(void * args)
{
    SOCKET sc=accept(s,0,0);
    if(sc==INVALID_SOCKET)
    {
        printf("sc Error");
    }
    creatThread();

    printf("----------客戶端已經連線到本機的%d執行緒連線!\n",threadCount-2);
#define BUF_SIZE 4096
    int receByt=0;
    while(1)
    {
        char buf[BUF_SIZE];
        receByt=recv(sc,buf,BUF_SIZE,0);
        buf[receByt]='\0';
        if(receByt>0)
        {
            printf("執行緒接收的訊息是:%s\n",buf);
        }
        else
        {
            printf("客戶端已退出,");
            break;
        }
            
    }
    int ic=closesocket(sc);
    printf("伺服器結束連線!\n");
    return NULL;
}

void creatThread()
{
    pthread_create(&t[threadCount++],NULL,receiveWork,NULL);
}


void Receive()
{
    WSAData wsd;
    WSAStartup(MAKEWORD(2,0),&wsd);    
    s=socket(AF_INET,SOCK_STREAM,IPPROTO_TCP);
    if(s==INVALID_SOCKET)
    {
        printf("socket created Error");
    }
    struct sockaddr_in ch;
    memset(&ch,0,sizeof(ch));
    ch.sin_family=AF_INET;
    ch.sin_addr.s_addr=INADDR_ANY;
    ch.sin_port=htons(1041);
    int b=bind(s,(struct sockaddr *) &ch,sizeof(ch));
    if(b==SOCKET_ERROR)
    {
        printf("bind 失敗,出錯程式碼是:%d\n",WSAGetLastError());
        exit(0);
    }
#define QUEUE_SIZE 5
    int l=listen(s,QUEUE_SIZE);
    printf("正在監聽本機的1041埠!\n");
    
    creatThread();

    for(int i=0;i<1000;i++)
    {
        pthread_join(t[i],NULL);
    }

int is=closesocket(s);
}



void Send()
{
    WSAData wsd;
    WSAStartup(MAKEWORD(2,0),&wsd);

    SOCKET s =NULL;
    s=socket(AF_INET,SOCK_STREAM,IPPROTO_TCP);
    if(s==INVALID_SOCKET)
    {
        printf("socket created Error");
    }
    struct sockaddr_in ch;
    memset(&ch,0,sizeof(ch));
    ch.sin_family=AF_INET;
    ch.sin_addr.s_addr=inet_addr("127.0.0.1");
    ch.sin_port=htons(1041);

    int c=connect(s,(struct sockaddr *) &ch,sizeof(ch));
    printf("已經連線到伺服器的1041埠!現在可以向伺服器傳送訊息了!\n");
#define BUF_SIZE 4096
    char info[1024],buf[BUF_SIZE];

    while(1)
    {
        gets(info);
        if(info[0]=='\0')
            break;
        strcpy(buf,info);
        int nsend=send(s,buf,strlen(buf),0);
    }
    int ic=closesocket(s);
}

 

相關文章